From 7cee5ee8a6749c29aa8dff1386fa559900973447 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 14 Feb 2023 13:02:15 -0800 Subject: [PATCH 01/19] saving kit changes --- build.gradle | 37 +++- .../com/mparticle/kits/ApptentiveKit.kt | 168 +++--------------- .../com/mparticle/kits/CustomDataParser.kt | 4 +- .../mparticle/kits/KitRegistrationListener.kt | 5 + .../kotlin/com/mparticle/kits/StringUtils.kt | 12 +- 5 files changed, 68 insertions(+), 158 deletions(-) create mode 100644 src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt diff --git a/build.gradle b/build.gradle index 0669712..1414a9d 100644 --- a/build.gradle +++ b/build.gradle @@ -6,8 +6,10 @@ buildscript { repositories { google() - mavenLocal() mavenCentral() + maven { + url "https://apptentive.jfrog.io/artifactory/NewAndroidSDK" + } } dependencies { @@ -20,6 +22,7 @@ buildscript { plugins { id "org.sonarqube" version "3.5.0.2730" id "org.jlleitschuh.gradle.ktlint" version "11.1.0" + id 'org.gradle.maven-publish' } sonarqube { @@ -43,6 +46,36 @@ android { } } +task androidSourcesJar(type: Jar) { + getArchiveClassifier().set('sources') + from android.sourceSets.main.java.srcDirs +} + +publishing { + publications { + mavenJava(MavenPublication) { + groupId = 'com.mparticle' + artifactId = 'android-apptentive-kit' + version = "6.0.1" + artifact("$buildDir/outputs/aar/android-apptentive-kit-release.aar") + artifact androidSourcesJar + } + } + repositories { + mavenLocal() + } +} + +allprojects { + repositories { + google() + mavenCentral() + maven { + url "https://apptentive.jfrog.io/artifactory/NewAndroidSDK" + } + } +} + dependencies { - api 'com.apptentive:apptentive-android:5.8.4' + implementation 'com.apptentive:apptentive-kit-android:6.0.3-public' } diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index b0c130a..3fb4c2d 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -2,32 +2,26 @@ package com.mparticle.kits import android.app.Application import android.content.Context -import com.apptentive.android.sdk.Apptentive -import com.apptentive.android.sdk.ApptentiveConfiguration -import com.apptentive.android.sdk.ApptentiveLog -import com.apptentive.android.sdk.ApptentiveNotifications -import com.apptentive.android.sdk.conversation.Conversation -import com.apptentive.android.sdk.model.CommerceExtendedData -import com.apptentive.android.sdk.model.ExtendedData -import com.apptentive.android.sdk.notifications.ApptentiveNotification -import com.apptentive.android.sdk.notifications.ApptentiveNotificationCenter -import com.apptentive.android.sdk.notifications.ApptentiveNotificationObserver +import android.util.Log +import apptentive.com.android.feedback.Apptentive +import apptentive.com.android.feedback.ApptentiveActivityInfo +import apptentive.com.android.feedback.ApptentiveConfiguration +import apptentive.com.android.feedback.RegisterResult import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType -import com.mparticle.commerce.CommerceEvent -import com.mparticle.commerce.TransactionAttributes import com.mparticle.kits.KitIntegration.AttributeListener -import com.mparticle.kits.KitIntegration.CommerceListener -import org.json.JSONException -import java.math.BigDecimal import java.util.* -class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, CommerceListener, - AttributeListener, ApptentiveNotificationObserver { +class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, + AttributeListener { private var enableTypeDetection = false private var lastKnownFirstName: String? = null private var lastKnownLastName: String? = null + + lateinit var apptentiveActivityInfo: ApptentiveActivityInfo + + override fun getName(): String = NAME override fun onKitCreate( settings: Map, @@ -41,21 +35,17 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, CommerceLi if (apptentiveAppKey != null && apptentiveAppSignature != null) { val configuration = ApptentiveConfiguration(apptentiveAppKey, apptentiveAppSignature) - Apptentive.register(context.applicationContext as Application, configuration) - ApptentiveNotificationCenter.defaultCenter() - .addObserver( - ApptentiveNotifications.NOTIFICATION_CONVERSATION_STATE_DID_CHANGE, - this - ) + Apptentive.register(context.applicationContext as Application, configuration) { registerResult -> + if (registerResult is RegisterResult.Success) { + Apptentive.setMParticleId(currentUser?.id.toString()) + } + } + } + Apptentive.registerApptentiveActivityInfoCallback(apptentiveActivityInfo) return emptyList() } - override fun onKitDestroy() { - super.onKitDestroy() - ApptentiveNotificationCenter.defaultCenter().removeObserver(this) - } - override fun setOptOut(optedOut: Boolean): List = emptyList() override fun setUserIdentity(identityType: IdentityType, id: String) { @@ -161,127 +151,16 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, CommerceLi return messages } - override fun logLtvIncrease( - valueIncreased: BigDecimal, - valueTotal: BigDecimal, - eventName: String, - contextInfo: Map - ): List = emptyList() - - override fun logEvent(event: CommerceEvent): List { - if (!KitUtils.isEmpty(event.productAction)) { - try { - val eventActionAttributes = HashMap() - CommerceEventUtils.extractActionAttributes(event, eventActionAttributes) - var apptentiveCommerceData: CommerceExtendedData? = null - val transactionAttributes = event.transactionAttributes - if (transactionAttributes != null) { - - apptentiveCommerceData = setTransactionAttributes( - transactionAttributes, - eventActionAttributes, - event - ) - } - if (apptentiveCommerceData != null) { - engage( - context, String.format("eCommerce - %s", event.productAction), - event.customAttributeStrings, - apptentiveCommerceData - ) - val messages = LinkedList() - messages.add(ReportingMessage.fromEvent(this, event)) - return messages - } - } catch (jse: JSONException) { - } - } - return emptyList() - } - - private fun setTransactionAttributes( - transactionAttributes: TransactionAttributes, - eventActionAttributes: HashMap, - event: CommerceEvent - ): CommerceExtendedData { - val apptentiveCommerceData = CommerceExtendedData() - val transactionId = transactionAttributes.id - if (!KitUtils.isEmpty(transactionId)) { - apptentiveCommerceData.setId(transactionId) - } - val transRevenue = transactionAttributes.revenue - if (transRevenue != null) { - apptentiveCommerceData.setRevenue(transRevenue) - } - val transShipping = transactionAttributes.shipping - if (transShipping != null) { - apptentiveCommerceData.setShipping(transShipping) - } - val transTax = transactionAttributes.tax - if (transTax != null) { - apptentiveCommerceData.setTax(transTax) - } - val transAffiliation = transactionAttributes.affiliation - if (!KitUtils.isEmpty(transAffiliation)) { - apptentiveCommerceData.setAffiliation(transAffiliation) - } - var transCurrency = - eventActionAttributes[CommerceEventUtils.Constants.ATT_ACTION_CURRENCY_CODE] - if (KitUtils.isEmpty(transCurrency)) { - transCurrency = CommerceEventUtils.Constants.DEFAULT_CURRENCY_CODE - } - apptentiveCommerceData.setCurrency(transCurrency) - - // Add each item - val productList = event.products - if (productList != null) { - for (product in productList) { - val item = CommerceExtendedData.Item() - item.setId(product.sku) - item.setName(product.name) - item.setCategory(product.category) - item.setPrice(product.unitPrice) - item.setQuantity(product.quantity) - item.setCurrency(transCurrency) - apptentiveCommerceData.addItem(item) - } - } - return apptentiveCommerceData - } - - //region Notifications - override fun onReceiveNotification(notification: ApptentiveNotification) { - if (notification.hasName(ApptentiveNotifications.NOTIFICATION_CONVERSATION_STATE_DID_CHANGE)) { - val conversation = notification.getRequiredUserInfo( - ApptentiveNotifications.NOTIFICATION_KEY_CONVERSATION, - Conversation::class.java - ) - if (conversation != null && conversation.hasActiveState()) { - val currentUser = currentUser - if (currentUser == null) { - ApptentiveLog.w(NO_CURRENT_USER_LOG_MESSAGE) - return - } - val userId = currentUser.id.toString() - ApptentiveLog.v("Updating mParticle id: %s", ApptentiveLog.hideIfSanitized(userId)) - conversation.person.mParticleId = userId - } - } - } - - //endregion //region Helpers private fun engage(context: Context, event: String, customData: Map?) { - engage(context, event, customData, *arrayOf()) + engage(event, customData) } private fun engage( - context: Context, event: String, customData: Map?, - vararg extendedData: ExtendedData ) { - Apptentive.engage(context, event, parseCustomData(customData), *extendedData) + Apptentive.engage( event, parseCustomData(customData)) } /* Apptentive SDK does not provide a function which accepts Object as custom data so we need to cast */ @@ -302,7 +181,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, CommerceLi Apptentive.addCustomPersonData(key + SUFFIX_KEY_NUMBER, typedValue) } else -> { - ApptentiveLog.e("Unexpected custom person data type: %s", typedValue?.javaClass) + Log.e("mParticle-CustomData","Unexpected custom person data type:${typedValue?.javaClass}") } } } @@ -329,10 +208,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, CommerceLi res[key + SUFFIX_KEY_NUMBER] = typedValue } else -> { - ApptentiveLog.e( - "Unexpected custom data type: %s", - typedValue?.javaClass - ) + Log.e("mParticle-CustomData","Unexpected custom data type:${typedValue?.javaClass}") } } } diff --git a/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt b/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt index 65e9b23..0f012e1 100644 --- a/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt +++ b/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt @@ -1,6 +1,6 @@ package com.mparticle.kits -import com.apptentive.android.sdk.ApptentiveLog +import android.util.Log import kotlin.Any import kotlin.Exception import kotlin.String @@ -19,7 +19,7 @@ internal object CustomDataParser { return try { if (value != null) parseValueGuarded(value) else null } catch (e: Exception) { - ApptentiveLog.e(e, "Unable to parse value: '%s'", value) + Log.e("MParticle-Util", "Unable to parse value: $value") value } } diff --git a/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt b/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt new file mode 100644 index 0000000..0143bff --- /dev/null +++ b/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt @@ -0,0 +1,5 @@ +package com.mparticle.kits + +interface KitRegistrationListener { + fun onKitCreated() +} \ No newline at end of file diff --git a/src/main/kotlin/com/mparticle/kits/StringUtils.kt b/src/main/kotlin/com/mparticle/kits/StringUtils.kt index 311e2e4..06ccb7b 100644 --- a/src/main/kotlin/com/mparticle/kits/StringUtils.kt +++ b/src/main/kotlin/com/mparticle/kits/StringUtils.kt @@ -1,7 +1,6 @@ package com.mparticle.kits -import com.apptentive.android.sdk.ApptentiveLog -import com.apptentive.android.sdk.ApptentiveLogTag +import android.util.Log internal object StringUtils { @JvmStatic @@ -16,12 +15,9 @@ internal object StringUtils { if (flag != null) { return flag } - ApptentiveLog.w( - ApptentiveLogTag.UTIL, - "Unable to parse boolean flag '%s': %s", - key, - value - ) + Log.w( + "MPartile-Util", + "Unable to parse boolean flag $key: $value") } return defaultValue } From 5643b6f520c032d0050918b174f896bc6c756a5b Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Fri, 17 Feb 2023 17:46:41 -0800 Subject: [PATCH 02/19] Replaced Deprecated code --- build.gradle | 3 +- .../com/mparticle/kits/ApptentiveKit.kt | 186 ++++++++++++------ .../mparticle/kits/KitRegistrationListener.kt | 26 ++- .../kotlin/com/mparticle/kits/StringUtils.kt | 32 +-- .../com/mparticle/kits/ApptentiveKitTest.kt | 122 +++++++++++- 5 files changed, 275 insertions(+), 94 deletions(-) diff --git a/build.gradle b/build.gradle index 1414a9d..32cba3b 100644 --- a/build.gradle +++ b/build.gradle @@ -56,7 +56,7 @@ publishing { mavenJava(MavenPublication) { groupId = 'com.mparticle' artifactId = 'android-apptentive-kit' - version = "6.0.1" + version = "6.0.4" artifact("$buildDir/outputs/aar/android-apptentive-kit-release.aar") artifact androidSourcesJar } @@ -78,4 +78,5 @@ allprojects { dependencies { implementation 'com.apptentive:apptentive-kit-android:6.0.3-public' + testImplementation 'io.mockk:mockk:1.13.3' } diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 3fb4c2d..19b842f 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -4,24 +4,25 @@ import android.app.Application import android.content.Context import android.util.Log import apptentive.com.android.feedback.Apptentive -import apptentive.com.android.feedback.ApptentiveActivityInfo import apptentive.com.android.feedback.ApptentiveConfiguration import apptentive.com.android.feedback.RegisterResult import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType -import com.mparticle.kits.KitIntegration.AttributeListener +import com.mparticle.consent.ConsentState +import com.mparticle.identity.MParticleUser +import com.mparticle.kits.KitIntegration.IdentityListener +import com.mparticle.kits.KitIntegration.UserAttributeListener import java.util.* +import kotlin.collections.HashMap -class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, - AttributeListener { - private var enableTypeDetection = false +class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityListener, + UserAttributeListener { + private var enableTypeDetection = true private var lastKnownFirstName: String? = null private var lastKnownLastName: String? = null - lateinit var apptentiveActivityInfo: ApptentiveActivityInfo - - + //region KitIntegration override fun getName(): String = NAME override fun onKitCreate( settings: Map, @@ -40,79 +41,93 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, Apptentive.setMParticleId(currentUser?.id.toString()) } } - } - Apptentive.registerApptentiveActivityInfoCallback(apptentiveActivityInfo) return emptyList() } override fun setOptOut(optedOut: Boolean): List = emptyList() - override fun setUserIdentity(identityType: IdentityType, id: String) { - if (identityType == IdentityType.Email) { - Apptentive.setPersonEmail(id) - } else if (identityType == IdentityType.CustomerId) { - if (KitUtils.isEmpty(Apptentive.getPersonName())) { - // Use id as customer name iff no full name is set yet. - Apptentive.setPersonName(id) - } - } + override fun supportsAttributeLists(): Boolean = false + override fun onConsentStateUpdated( + oldState: ConsentState?, + newState: ConsentState?, + user: FilteredMParticleUser? + ) { + //Ignored } - override fun setUserAttribute(attributeKey: String, attributeValue: String) { - if (attributeKey.equals(MParticle.UserAttributes.FIRSTNAME, true)) { - lastKnownFirstName = attributeValue - } else if (attributeKey.equals(MParticle.UserAttributes.LASTNAME, true)) { - lastKnownLastName = attributeValue - } else { - addCustomPersonData(attributeKey, attributeValue) - return - } - var fullName = "" - if (!KitUtils.isEmpty(lastKnownFirstName)) { - fullName += lastKnownFirstName + //endregion + + //region UserAttributeListener + override fun onIncrementUserAttribute( + key: String?, + incrementedBy: Number?, + value: String?, + user: FilteredMParticleUser? + ) { + //Ignored + } + + override fun onRemoveUserAttribute(key: String?, user: FilteredMParticleUser?) { + key?.let { + Apptentive.removeCustomPersonData(it) } - if (!KitUtils.isEmpty(lastKnownLastName)) { - if (fullName.isNotEmpty()) { - fullName += "" + } + + override fun onSetUserAttribute(key: String?, value: Any?, user: FilteredMParticleUser?) { + if (key != null && value != null) { + when (key.lowercase()){ + MParticle.UserAttributes.FIRSTNAME.lowercase() -> { + lastKnownFirstName = value.toString() + } + MParticle.UserAttributes.LASTNAME.lowercase() -> { + lastKnownLastName = value.toString() + } + else -> { + Log.d("mParticle", "Adding custom data $key $value") + addCustomPersonData(key, value.toString()) + return + } } - fullName += lastKnownLastName + val fullName = listOfNotNull(lastKnownLastName, lastKnownFirstName).joinToString(separator = " ") + Log.d("mParticle", "Setting person name $fullName") + if (fullName.isNotBlank()) Apptentive.setPersonName(fullName.trim()) } - Apptentive.setPersonName(fullName.trim { it <= ' ' }) } - override fun setUserAttributeList(key: String, list: List) {} - override fun supportsAttributeLists(): Boolean = false + override fun onSetUserTag(key: String?, user: FilteredMParticleUser?) { + //Ignored + } + + override fun onSetUserAttributeList( + attributeKey: String?, + attributeValueList: MutableList?, + user: FilteredMParticleUser? + ) { + //Ignored + } - override fun setAllUserAttributes( - attributes: Map, - attributeLists: Map> + override fun onSetAllUserAttributes( + userAttributes: MutableMap?, + userAttributeLists: MutableMap>?, + user: FilteredMParticleUser? ) { - var firstName = "" - var lastName = "" - for ((key, value) in attributes) { - if (key.equals(MParticle.UserAttributes.FIRSTNAME, true)) { - firstName = value - } else if (key.equals(MParticle.UserAttributes.LASTNAME, true)) { - lastName = value - } else { - addCustomPersonData(key, value) + userAttributes?.let { userAttribute -> + val firstName = userAttribute[MParticle.UserAttributes.FIRSTNAME] ?: "" + val lastName = userAttribute[MParticle.UserAttributes.LASTNAME] ?: "" + val fullName = listOfNotNull(firstName, lastName).joinToString(separator = " ") + if (fullName.isNotBlank()) Apptentive.setPersonName(fullName.trim()) + userAttribute.filterKeys { key -> + key != MParticle.UserAttributes.FIRSTNAME && key != MParticle.UserAttributes.LASTNAME + }.map { + addCustomPersonData(it.key, it.value) } } - val fullName = if (!KitUtils.isEmpty(firstName) && !KitUtils.isEmpty(lastName)) { - "$firstName $lastName" - } else { - firstName + lastName - } - Apptentive.setPersonName(fullName.trim { it <= ' ' }) } - override fun removeUserAttribute(key: String) { - Apptentive.removeCustomPersonData(key) - } + //endregion - override fun removeUserIdentity(identityType: IdentityType) {} - override fun logout(): List = emptyList() + //region EventListener override fun leaveBreadcrumb(breadcrumb: String): List = emptyList() override fun logError( @@ -149,9 +164,58 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, ) ) return messages + } //endregion + + //region IdentityListener + override fun onIdentifyCompleted( + mParticleUser: MParticleUser?, + identityApiRequest: FilteredIdentityApiRequest? + ) { + setUserIdentity(mParticleUser) + } + + override fun onLoginCompleted( + mParticleUser: MParticleUser?, + identityApiRequest: FilteredIdentityApiRequest? + ) { + setUserIdentity(mParticleUser) + } + + override fun onLogoutCompleted( + mParticleUser: MParticleUser?, + identityApiRequest: FilteredIdentityApiRequest? + ) { + setUserIdentity(mParticleUser) } + override fun onModifyCompleted( + mParticleUser: MParticleUser?, + identityApiRequest: FilteredIdentityApiRequest? + ) { + setUserIdentity(mParticleUser) + } + + override fun onUserIdentified(mParticleUser: MParticleUser?) { + Apptentive.setMParticleId(mParticleUser?.id.toString()) + } + + //endregion + //region Helpers + private fun setUserIdentity(user: MParticleUser?) { + user?.userIdentities?.entries?.forEach { + when (it.key) { + IdentityType.CustomerId -> { + if (KitUtils.isEmpty(Apptentive.getPersonName())) { + // Use id as customer name iff no full name is set yet. + Apptentive.setPersonName(it.value) + } + } + IdentityType.Email -> Apptentive.setPersonEmail(it.value) + else -> Log.d("UserIdentity", "Other type") + } + } + } private fun engage(context: Context, event: String, customData: Map?) { engage(event, customData) } diff --git a/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt b/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt index 0143bff..bc97574 100644 --- a/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt +++ b/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt @@ -1,5 +1,27 @@ package com.mparticle.kits -interface KitRegistrationListener { - fun onKitCreated() +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.util.Log +import apptentive.com.android.feedback.Apptentive +import apptentive.com.android.feedback.ApptentiveActivityInfo +import com.mparticle.MParticle + +object ApptentiveKitListener { + fun registerApptentiveActivityContext(callback: ApptentiveActivityInfo) { + if (MParticle.getInstance()?.isKitActive(MParticle.ServiceProviders.APPTENTIVE) == true) { + Apptentive.registerApptentiveActivityInfoCallback(callback) + } else { + val filter = IntentFilter(MParticle.ServiceProviders.BROADCAST_ACTIVE + MParticle.ServiceProviders.APPTENTIVE); + callback.getApptentiveActivityInfo().registerReceiver(object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action?.startsWith(MParticle.ServiceProviders.BROADCAST_ACTIVE) == true) { + Apptentive.registerApptentiveActivityInfoCallback(callback) + } + } + }, filter) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/com/mparticle/kits/StringUtils.kt b/src/main/kotlin/com/mparticle/kits/StringUtils.kt index 06ccb7b..cb5f0fc 100644 --- a/src/main/kotlin/com/mparticle/kits/StringUtils.kt +++ b/src/main/kotlin/com/mparticle/kits/StringUtils.kt @@ -1,7 +1,5 @@ package com.mparticle.kits -import android.util.Log - internal object StringUtils { @JvmStatic fun tryParseSettingFlag( @@ -10,29 +8,21 @@ internal object StringUtils { defaultValue: Boolean ): Boolean { val value = settings[key] - if (value != null) { - val flag = value.toBoolean() - if (flag != null) { - return flag - } - Log.w( - "MPartile-Util", - "Unable to parse boolean flag $key: $value") - } - return defaultValue + return value?.toBoolean() ?: defaultValue } @JvmStatic fun tryParseNumber(value: String): Number? { val longValue = tryParseLong(value) return if (longValue != null) { - if (longValue >= Int.MIN_VALUE && longValue <= Int.MAX_VALUE) { - longValue.toInt() - } else longValue + if (isInIntegerRange(longValue)) longValue.toInt() + else longValue } else tryParseDouble(value) } - fun tryParseLong(value: String): Long? { + private fun isInIntegerRange(value: Long): Boolean = value >= Int.MIN_VALUE && value <= Int.MAX_VALUE + + private fun tryParseLong(value: String): Long? { return try { value.toLong() } catch (e: NumberFormatException) { @@ -40,19 +30,11 @@ internal object StringUtils { } } - fun tryParseDouble(value: String): Double? { + private fun tryParseDouble(value: String): Double? { return try { java.lang.Double.valueOf(value) } catch (e: NumberFormatException) { null } } - - fun tryParseBoolean(value: String): Boolean? { - return try { - value.toBoolean() - } catch (e: NumberFormatException) { - null - } - } } \ No newline at end of file diff --git a/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt b/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt index 96c1368..5a4709e 100644 --- a/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt +++ b/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt @@ -1,13 +1,20 @@ package com.mparticle.kits import android.content.Context +import apptentive.com.android.feedback.Apptentive +import com.mparticle.MParticle +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.verify +import junit.framework.TestCase.* import org.junit.Assert import org.junit.Test import org.mockito.Mockito class ApptentiveKitTest { - private val kit: KitIntegration - get() = ApptentiveKit() + private val kit: ApptentiveKit + get() = ApptentiveKit() @Test @Throws(Exception::class) @@ -26,9 +33,9 @@ class ApptentiveKitTest { var e: Exception? = null try { val kit = kit - val settings = HashMap() + val settings = HashMap() settings["fake setting"] = "fake" - kit.onKitCreate(settings, Mockito.mock(Context::class.java)) + (kit as KitIntegration).onKitCreate(settings, Mockito.mock(Context::class.java)) } catch (ex: Exception) { e = ex } @@ -48,4 +55,109 @@ class ApptentiveKitTest { } Assert.fail("$className not found as a known integration.") } -} \ No newline at end of file + + @Test + fun testLastNameValueOnSetUserAttribute() { + val user = mockk() + mockkStatic(Apptentive::class) + every { Apptentive.setPersonName(any()) } returns Unit + val key = MParticle.UserAttributes.LASTNAME + val value = "Doe" + + // when + kit.onSetUserAttribute(key, value, user) + + // then + verify { Apptentive.setPersonName("Doe") } + } + + @Test + fun testFirstNameValueOnSetUserAttribute() { + val user = mockk() + mockkStatic(Apptentive::class) + every { Apptentive.setPersonName(any()) } returns Unit + val key = MParticle.UserAttributes.FIRSTNAME + val value = "John" + + // when + kit.onSetUserAttribute(key, value, user) + + // then + verify { Apptentive.setPersonName("John") } + } + + @Test + fun testPersonCustomData() { + val user = mockk() + mockkStatic(Apptentive::class) + every { Apptentive.addCustomPersonData(any(), any()) } returns Unit + every { Apptentive.addCustomPersonData(any(), 30) } returns Unit + val key = "age" + val value = "30" + + // when + kit.onSetUserAttribute(key, value, user) + + // then + verify { Apptentive.addCustomPersonData("age_number", 30) } + } + + @Test + fun testOnSetUserAttributeWithNullKey() { + val user = mockk() + mockkStatic(Apptentive::class) + + val key = null + val value = "30" + + // when + kit.onSetUserAttribute(key, value, user) + + // then + verify(exactly = 0) { Apptentive.setPersonName(any()) } + verify(exactly = 0) { Apptentive.addCustomPersonData(any(), any()) } + verify(exactly = 0) { Apptentive.addCustomPersonData(any(), any()) } + verify(exactly = 0) { Apptentive.addCustomPersonData(any(), any()) } + } + + // onSetAllUserAttributes test + + @Test + fun testFullNameInTheUserAttributes() { + val userAttributes = mutableMapOf( + MParticle.UserAttributes.FIRSTNAME to "John", + MParticle.UserAttributes.LASTNAME to "Doe" + ) + + val user = mockk() + mockkStatic(Apptentive::class) + every { Apptentive.setPersonName(any()) } returns Unit + + // when + kit.onSetAllUserAttributes(userAttributes, null, user) + + verify { + Apptentive.setPersonName("John Doe") + } + } + + @Test + fun testListOfCustomPersonData() { + val userAttributes = mutableMapOf( + "key1" to "value1", + "key2" to "20" + ) + val user = mockk() + mockkStatic(Apptentive::class) + every { Apptentive.addCustomPersonData(any(), any()) } returns Unit + every { Apptentive.addCustomPersonData(any(), 20) } returns Unit + + kit.onSetAllUserAttributes(userAttributes, null, user) + + verify { + Apptentive.addCustomPersonData("key1", "value1") + Apptentive.addCustomPersonData("key2", "20") + Apptentive.addCustomPersonData("key2_number", 20) + } + } +} From 6dca8d5eaf8a696b7c0474299edd6a9cfe6cf4e3 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 21 Feb 2023 15:23:13 -0800 Subject: [PATCH 03/19] cleanup --- build.gradle | 8 ++-- .../com/mparticle/kits/ApptentiveKit.kt | 38 ++++++++++++------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 32cba3b..f162831 100644 --- a/build.gradle +++ b/build.gradle @@ -40,9 +40,7 @@ apply plugin: 'kotlin-android' android { namespace 'com.mparticle.kits.apptentive' defaultConfig { - minSdkVersion 16 - resValue "string", "apptentive_distribution", "mParticle" - resValue "string", "apptentive_distribution_version", project.version + minSdkVersion 21 } } @@ -56,7 +54,7 @@ publishing { mavenJava(MavenPublication) { groupId = 'com.mparticle' artifactId = 'android-apptentive-kit' - version = "6.0.4" + version = "6.0.7" artifact("$buildDir/outputs/aar/android-apptentive-kit-release.aar") artifact androidSourcesJar } @@ -77,6 +75,6 @@ allprojects { } dependencies { - implementation 'com.apptentive:apptentive-kit-android:6.0.3-public' + implementation 'com.apptentive:apptentive-kit-android:6.0.3-public03' testImplementation 'io.mockk:mockk:1.13.3' } diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 19b842f..b06369c 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -2,10 +2,13 @@ package com.mparticle.kits import android.app.Application import android.content.Context +import android.content.pm.PackageManager.NameNotFoundException import android.util.Log import apptentive.com.android.feedback.Apptentive import apptentive.com.android.feedback.ApptentiveConfiguration import apptentive.com.android.feedback.RegisterResult +import apptentive.com.android.util.InternalUseOnly +import apptentive.com.android.util.LogLevel import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType @@ -24,6 +27,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi //region KitIntegration override fun getName(): String = NAME + @OptIn(InternalUseOnly::class) override fun onKitCreate( settings: Map, context: Context @@ -36,6 +40,10 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi if (apptentiveAppKey != null && apptentiveAppSignature != null) { val configuration = ApptentiveConfiguration(apptentiveAppKey, apptentiveAppSignature) + configuration.logLevel = LogLevel.Verbose + configuration.shouldSanitizeLogMessages = false + configuration.distributionVersion = getSDKVersion(context) + configuration.distributionName = "mParticle" Apptentive.register(context.applicationContext as Application, configuration) { registerResult -> if (registerResult is RegisterResult.Success) { Apptentive.setMParticleId(currentUser?.id.toString()) @@ -84,13 +92,11 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi lastKnownLastName = value.toString() } else -> { - Log.d("mParticle", "Adding custom data $key $value") addCustomPersonData(key, value.toString()) return } } val fullName = listOfNotNull(lastKnownLastName, lastKnownFirstName).joinToString(separator = " ") - Log.d("mParticle", "Setting person name $fullName") if (fullName.isNotBlank()) Apptentive.setPersonName(fullName.trim()) } } @@ -143,7 +149,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi ): List = emptyList() override fun logEvent(event: MPEvent): List { - engage(context, event.eventName, event.customAttributeStrings) + engage(event.eventName, event.customAttributeStrings) val messageList = LinkedList() messageList.add(ReportingMessage.fromEvent(this, event)) return messageList @@ -153,7 +159,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi screenName: String, eventAttributes: Map ): List { - engage(context, screenName, eventAttributes) + engage(screenName, eventAttributes) val messages = LinkedList() messages.add( ReportingMessage( @@ -216,15 +222,9 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi } } } - private fun engage(context: Context, event: String, customData: Map?) { - engage(event, customData) - } - private fun engage( - event: String, - customData: Map?, - ) { - Apptentive.engage( event, parseCustomData(customData)) + private fun engage(event: String, customData: Map?) { + Apptentive.engage(event, parseCustomData(customData)) } /* Apptentive SDK does not provide a function which accepts Object as custom data so we need to cast */ @@ -280,7 +280,19 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi return res } return null - } //endregion + } + + private fun getSDKVersion(context: Context): String { + val packageManager = context.packageManager + return try { + val packageInfo = packageManager.getPackageInfo(context.packageName, 0) + packageInfo.versionCode.toString() + } catch (exception: NameNotFoundException) { + Log.e("mParticle", "There is a issue in getting the current SDK version from the PackageManager") + "1" + } + } + //endregion companion object { private const val APPTENTIVE_APP_KEY = "apptentiveAppKey" From 583d60d9ca5dd8a45aa69a5e54fa7b801f384a40 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 21 Feb 2023 17:32:47 -0800 Subject: [PATCH 04/19] enableTypeDetection false bydefault --- src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt | 2 +- src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index b06369c..0dbae1f 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -21,7 +21,7 @@ import kotlin.collections.HashMap class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityListener, UserAttributeListener { - private var enableTypeDetection = true + private var enableTypeDetection = false private var lastKnownFirstName: String? = null private var lastKnownLastName: String? = null diff --git a/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt b/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt index 5a4709e..68f404c 100644 --- a/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt +++ b/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt @@ -99,7 +99,8 @@ class ApptentiveKitTest { kit.onSetUserAttribute(key, value, user) // then - verify { Apptentive.addCustomPersonData("age_number", 30) } + // enableTypeDetection is false & 30 will be passed as string + verify { Apptentive.addCustomPersonData("age", "30") } } @Test @@ -151,13 +152,11 @@ class ApptentiveKitTest { mockkStatic(Apptentive::class) every { Apptentive.addCustomPersonData(any(), any()) } returns Unit every { Apptentive.addCustomPersonData(any(), 20) } returns Unit - kit.onSetAllUserAttributes(userAttributes, null, user) verify { Apptentive.addCustomPersonData("key1", "value1") Apptentive.addCustomPersonData("key2", "20") - Apptentive.addCustomPersonData("key2_number", 20) } } } From 29fde03133a5501530224844d57819fa1cc482b7 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Thu, 23 Feb 2023 10:34:15 -0800 Subject: [PATCH 05/19] use VERSION_NAME --- src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 0dbae1f..30caf98 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -42,7 +42,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi val configuration = ApptentiveConfiguration(apptentiveAppKey, apptentiveAppSignature) configuration.logLevel = LogLevel.Verbose configuration.shouldSanitizeLogMessages = false - configuration.distributionVersion = getSDKVersion(context) + configuration.distributionVersion = com.mparticle.BuildConfig.VERSION_NAME configuration.distributionName = "mParticle" Apptentive.register(context.applicationContext as Application, configuration) { registerResult -> if (registerResult is RegisterResult.Success) { @@ -202,7 +202,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi } override fun onUserIdentified(mParticleUser: MParticleUser?) { - Apptentive.setMParticleId(mParticleUser?.id.toString()) + //Ignored } //endregion From 8fd78b9295ed834b2d44fb17fc2c0ea82579ccbc Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Thu, 23 Feb 2023 16:04:25 -0800 Subject: [PATCH 06/19] PR updates --- .../com/mparticle/kits/ApptentiveKit.kt | 32 ++++++------------- .../mparticle/kits/KitRegistrationListener.kt | 27 ---------------- .../kotlin/com/mparticle/kits/KitUtils.kt | 24 ++++++++++++++ .../kotlin/com/mparticle/kits/StringUtils.kt | 2 +- 4 files changed, 35 insertions(+), 50 deletions(-) delete mode 100644 src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt create mode 100644 src/main/kotlin/com/mparticle/kits/KitUtils.kt diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 30caf98..a64bb3d 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -2,13 +2,13 @@ package com.mparticle.kits import android.app.Application import android.content.Context -import android.content.pm.PackageManager.NameNotFoundException -import android.util.Log import apptentive.com.android.feedback.Apptentive import apptentive.com.android.feedback.ApptentiveConfiguration import apptentive.com.android.feedback.RegisterResult import apptentive.com.android.util.InternalUseOnly +import apptentive.com.android.util.Log import apptentive.com.android.util.LogLevel +import apptentive.com.android.util.LogTag import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType @@ -19,6 +19,7 @@ import com.mparticle.kits.KitIntegration.UserAttributeListener import java.util.* import kotlin.collections.HashMap +@OptIn(InternalUseOnly::class) class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityListener, UserAttributeListener { private var enableTypeDetection = false @@ -27,7 +28,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi //region KitIntegration override fun getName(): String = NAME - @OptIn(InternalUseOnly::class) + override fun onKitCreate( settings: Map, context: Context @@ -96,8 +97,8 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi return } } - val fullName = listOfNotNull(lastKnownLastName, lastKnownFirstName).joinToString(separator = " ") - if (fullName.isNotBlank()) Apptentive.setPersonName(fullName.trim()) + val fullName = listOfNotNull(lastKnownLastName, lastKnownFirstName).joinToString(separator = " ").trim() + if (fullName.isNotBlank()) Apptentive.setPersonName(fullName) } } @@ -213,12 +214,12 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi when (it.key) { IdentityType.CustomerId -> { if (KitUtils.isEmpty(Apptentive.getPersonName())) { - // Use id as customer name iff no full name is set yet. + // Use id as customer name if no full name is set yet. Apptentive.setPersonName(it.value) } } IdentityType.Email -> Apptentive.setPersonEmail(it.value) - else -> Log.d("UserIdentity", "Other type") + else -> Log.d(LogTag("mParticle"), "Other identity type") } } } @@ -245,7 +246,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi Apptentive.addCustomPersonData(key + SUFFIX_KEY_NUMBER, typedValue) } else -> { - Log.e("mParticle-CustomData","Unexpected custom person data type:${typedValue?.javaClass}") + Log.e(LogTag("mParticle"),"Unexpected custom person data type:${typedValue?.javaClass}") } } } @@ -272,7 +273,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi res[key + SUFFIX_KEY_NUMBER] = typedValue } else -> { - Log.e("mParticle-CustomData","Unexpected custom data type:${typedValue?.javaClass}") + Log.e(LogTag("mParticle"),"Unexpected custom data type:${typedValue?.javaClass}") } } } @@ -281,17 +282,6 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi } return null } - - private fun getSDKVersion(context: Context): String { - val packageManager = context.packageManager - return try { - val packageInfo = packageManager.getPackageInfo(context.packageName, 0) - packageInfo.versionCode.toString() - } catch (exception: NameNotFoundException) { - Log.e("mParticle", "There is a issue in getting the current SDK version from the PackageManager") - "1" - } - } //endregion companion object { @@ -300,8 +290,6 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi private const val ENABLE_TYPE_DETECTION = "enableTypeDetection" private const val SUFFIX_KEY_FLAG = "_flag" private const val SUFFIX_KEY_NUMBER = "_number" - private const val NO_CURRENT_USER_LOG_MESSAGE = - "Unable to update mParticle id: no current user" private const val KEY_REQUIRED = "Apptentive App Key is required. If you are migrating from a previous version, you may need to enter the new Apptentive App Key and Signature on the mParticle website." private const val SIGNATURE_REQUIRED = diff --git a/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt b/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt deleted file mode 100644 index bc97574..0000000 --- a/src/main/kotlin/com/mparticle/kits/KitRegistrationListener.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.mparticle.kits - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.util.Log -import apptentive.com.android.feedback.Apptentive -import apptentive.com.android.feedback.ApptentiveActivityInfo -import com.mparticle.MParticle - -object ApptentiveKitListener { - fun registerApptentiveActivityContext(callback: ApptentiveActivityInfo) { - if (MParticle.getInstance()?.isKitActive(MParticle.ServiceProviders.APPTENTIVE) == true) { - Apptentive.registerApptentiveActivityInfoCallback(callback) - } else { - val filter = IntentFilter(MParticle.ServiceProviders.BROADCAST_ACTIVE + MParticle.ServiceProviders.APPTENTIVE); - callback.getApptentiveActivityInfo().registerReceiver(object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - if (intent.action?.startsWith(MParticle.ServiceProviders.BROADCAST_ACTIVE) == true) { - Apptentive.registerApptentiveActivityInfoCallback(callback) - } - } - }, filter) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/mparticle/kits/KitUtils.kt b/src/main/kotlin/com/mparticle/kits/KitUtils.kt new file mode 100644 index 0000000..3d09c0f --- /dev/null +++ b/src/main/kotlin/com/mparticle/kits/KitUtils.kt @@ -0,0 +1,24 @@ +package com.mparticle.kits + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import apptentive.com.android.feedback.Apptentive +import apptentive.com.android.feedback.ApptentiveActivityInfo +import com.mparticle.MParticle + +fun registerApptentiveActivityContext(callback: ApptentiveActivityInfo) { + if (MParticle.getInstance()?.isKitActive(MParticle.ServiceProviders.APPTENTIVE) == true) { + Apptentive.registerApptentiveActivityInfoCallback(callback) + } else { + val filter = IntentFilter(MParticle.ServiceProviders.BROADCAST_ACTIVE + MParticle.ServiceProviders.APPTENTIVE); + callback.getApptentiveActivityInfo().registerReceiver(object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action?.startsWith(MParticle.ServiceProviders.BROADCAST_ACTIVE) == true) { + Apptentive.registerApptentiveActivityInfoCallback(callback) + } + } + }, filter) + } +} diff --git a/src/main/kotlin/com/mparticle/kits/StringUtils.kt b/src/main/kotlin/com/mparticle/kits/StringUtils.kt index cb5f0fc..404ece3 100644 --- a/src/main/kotlin/com/mparticle/kits/StringUtils.kt +++ b/src/main/kotlin/com/mparticle/kits/StringUtils.kt @@ -32,7 +32,7 @@ internal object StringUtils { private fun tryParseDouble(value: String): Double? { return try { - java.lang.Double.valueOf(value) + value.toDouble() } catch (e: NumberFormatException) { null } From 4e8d1ad082058596b9455d948fd537cff98305ca Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 28 Feb 2023 14:00:47 -0800 Subject: [PATCH 07/19] remove temporary code, fix for loglevel --- build.gradle | 25 +---------------- .../com/mparticle/kits/ApptentiveKit.kt | 18 ++++++++++-- .../com/mparticle/kits/ApptentiveKitUtils.kt | 28 +++++++++++++++++++ .../kotlin/com/mparticle/kits/KitUtils.kt | 24 ---------------- 4 files changed, 44 insertions(+), 51 deletions(-) create mode 100644 src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt delete mode 100644 src/main/kotlin/com/mparticle/kits/KitUtils.kt diff --git a/build.gradle b/build.gradle index f162831..6c2be3d 100644 --- a/build.gradle +++ b/build.gradle @@ -44,37 +44,14 @@ android { } } -task androidSourcesJar(type: Jar) { - getArchiveClassifier().set('sources') - from android.sourceSets.main.java.srcDirs -} - -publishing { - publications { - mavenJava(MavenPublication) { - groupId = 'com.mparticle' - artifactId = 'android-apptentive-kit' - version = "6.0.7" - artifact("$buildDir/outputs/aar/android-apptentive-kit-release.aar") - artifact androidSourcesJar - } - } - repositories { - mavenLocal() - } -} - allprojects { repositories { google() mavenCentral() - maven { - url "https://apptentive.jfrog.io/artifactory/NewAndroidSDK" - } } } dependencies { - implementation 'com.apptentive:apptentive-kit-android:6.0.3-public03' + implementation 'com.apptentive:apptentive-kit-android:6.0.3' testImplementation 'io.mockk:mockk:1.13.3' } diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index a64bb3d..0d94af3 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -14,6 +14,7 @@ import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType import com.mparticle.consent.ConsentState import com.mparticle.identity.MParticleUser +import com.mparticle.internal.Logger import com.mparticle.kits.KitIntegration.IdentityListener import com.mparticle.kits.KitIntegration.UserAttributeListener import java.util.* @@ -41,8 +42,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi if (apptentiveAppKey != null && apptentiveAppSignature != null) { val configuration = ApptentiveConfiguration(apptentiveAppKey, apptentiveAppSignature) - configuration.logLevel = LogLevel.Verbose - configuration.shouldSanitizeLogMessages = false + configuration.logLevel = getApptentiveLogLevel() configuration.distributionVersion = com.mparticle.BuildConfig.VERSION_NAME configuration.distributionName = "mParticle" Apptentive.register(context.applicationContext as Application, configuration) { registerResult -> @@ -97,7 +97,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi return } } - val fullName = listOfNotNull(lastKnownLastName, lastKnownFirstName).joinToString(separator = " ").trim() + val fullName = listOfNotNull(lastKnownFirstName, lastKnownLastName).joinToString(separator = " ").trim() if (fullName.isNotBlank()) Apptentive.setPersonName(fullName) } } @@ -209,6 +209,18 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi //endregion //region Helpers + private fun getApptentiveLogLevel(): LogLevel { + return when (Logger.getMinLogLevel()) { + MParticle.LogLevel.DEBUG -> LogLevel.Debug + MParticle.LogLevel.INFO -> LogLevel.Info + MParticle.LogLevel.ERROR -> LogLevel.Error + MParticle.LogLevel.WARNING -> LogLevel.Warning + MParticle.LogLevel.VERBOSE -> LogLevel.Verbose + MParticle.LogLevel.NONE -> LogLevel.Info + null -> LogLevel.Info + } + } + private fun setUserIdentity(user: MParticleUser?) { user?.userIdentities?.entries?.forEach { when (it.key) { diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt new file mode 100644 index 0000000..6e2d14a --- /dev/null +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt @@ -0,0 +1,28 @@ +package com.mparticle.kits + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import apptentive.com.android.feedback.Apptentive +import apptentive.com.android.feedback.ApptentiveActivityInfo +import com.mparticle.MParticle + + +object ApptentiveKitUtils { + fun registerApptentiveActivityContext(callback: ApptentiveActivityInfo) { + if (MParticle.getInstance()?.isKitActive(MParticle.ServiceProviders.APPTENTIVE) == true) { + Apptentive.registerApptentiveActivityInfoCallback(callback) + } else { + val filter = + IntentFilter(MParticle.ServiceProviders.BROADCAST_ACTIVE + MParticle.ServiceProviders.APPTENTIVE); + callback.getApptentiveActivityInfo().registerReceiver(object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action?.startsWith(MParticle.ServiceProviders.BROADCAST_ACTIVE) == true) { + Apptentive.registerApptentiveActivityInfoCallback(callback) + } + } + }, filter) + } + } +} diff --git a/src/main/kotlin/com/mparticle/kits/KitUtils.kt b/src/main/kotlin/com/mparticle/kits/KitUtils.kt deleted file mode 100644 index 3d09c0f..0000000 --- a/src/main/kotlin/com/mparticle/kits/KitUtils.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.mparticle.kits - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import apptentive.com.android.feedback.Apptentive -import apptentive.com.android.feedback.ApptentiveActivityInfo -import com.mparticle.MParticle - -fun registerApptentiveActivityContext(callback: ApptentiveActivityInfo) { - if (MParticle.getInstance()?.isKitActive(MParticle.ServiceProviders.APPTENTIVE) == true) { - Apptentive.registerApptentiveActivityInfoCallback(callback) - } else { - val filter = IntentFilter(MParticle.ServiceProviders.BROADCAST_ACTIVE + MParticle.ServiceProviders.APPTENTIVE); - callback.getApptentiveActivityInfo().registerReceiver(object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - if (intent.action?.startsWith(MParticle.ServiceProviders.BROADCAST_ACTIVE) == true) { - Apptentive.registerApptentiveActivityInfoCallback(callback) - } - } - }, filter) - } -} From ba43a9b2af42f1a6ea2ff6ed5041f3f838e8188f Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 28 Feb 2023 14:18:40 -0800 Subject: [PATCH 08/19] Cleanup & logtags --- .../com/mparticle/kits/ApptentiveKit.kt | 50 +++++++++++++------ .../com/mparticle/kits/CustomDataParser.kt | 11 ++-- .../kotlin/com/mparticle/kits/StringUtils.kt | 3 +- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 0d94af3..a3ed86d 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -22,8 +22,8 @@ import kotlin.collections.HashMap @OptIn(InternalUseOnly::class) class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityListener, - UserAttributeListener { - private var enableTypeDetection = false + UserAttributeListener { + private var enableTypeDetection = true private var lastKnownFirstName: String? = null private var lastKnownLastName: String? = null @@ -45,7 +45,10 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi configuration.logLevel = getApptentiveLogLevel() configuration.distributionVersion = com.mparticle.BuildConfig.VERSION_NAME configuration.distributionName = "mParticle" - Apptentive.register(context.applicationContext as Application, configuration) { registerResult -> + Apptentive.register( + context.applicationContext as Application, + configuration + ) { registerResult -> if (registerResult is RegisterResult.Success) { Apptentive.setMParticleId(currentUser?.id.toString()) } @@ -74,7 +77,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi value: String?, user: FilteredMParticleUser? ) { - //Ignored + //Ignored } override fun onRemoveUserAttribute(key: String?, user: FilteredMParticleUser?) { @@ -85,7 +88,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi override fun onSetUserAttribute(key: String?, value: Any?, user: FilteredMParticleUser?) { if (key != null && value != null) { - when (key.lowercase()){ + when (key.lowercase()) { MParticle.UserAttributes.FIRSTNAME.lowercase() -> { lastKnownFirstName = value.toString() } @@ -97,13 +100,18 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi return } } - val fullName = listOfNotNull(lastKnownFirstName, lastKnownLastName).joinToString(separator = " ").trim() - if (fullName.isNotBlank()) Apptentive.setPersonName(fullName) + val fullName = + listOfNotNull(lastKnownFirstName, lastKnownLastName).joinToString(separator = " ") + .trim() + if (fullName.isNotBlank()) { + Log.d(LogTag("mParticle"), "Setting user name $fullName") + Apptentive.setPersonName(fullName) + } } } override fun onSetUserTag(key: String?, user: FilteredMParticleUser?) { - //Ignored + //Ignored } override fun onSetUserAttributeList( @@ -122,8 +130,11 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi userAttributes?.let { userAttribute -> val firstName = userAttribute[MParticle.UserAttributes.FIRSTNAME] ?: "" val lastName = userAttribute[MParticle.UserAttributes.LASTNAME] ?: "" - val fullName = listOfNotNull(firstName, lastName).joinToString(separator = " ") - if (fullName.isNotBlank()) Apptentive.setPersonName(fullName.trim()) + val fullName = listOfNotNull(firstName, lastName).joinToString(separator = " ").trim() + if (fullName.isNotBlank()) { + Log.d(LogTag("mParticle"), "Setting user name $fullName") + Apptentive.setPersonName(fullName) + } userAttribute.filterKeys { key -> key != MParticle.UserAttributes.FIRSTNAME && key != MParticle.UserAttributes.LASTNAME }.map { @@ -224,13 +235,17 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi private fun setUserIdentity(user: MParticleUser?) { user?.userIdentities?.entries?.forEach { when (it.key) { - IdentityType.CustomerId -> { + IdentityType.CustomerId -> { if (KitUtils.isEmpty(Apptentive.getPersonName())) { // Use id as customer name if no full name is set yet. + Log.d(LogTag("mParticle"), "Setting customer id as user name ${it.value}") Apptentive.setPersonName(it.value) } } - IdentityType.Email -> Apptentive.setPersonEmail(it.value) + IdentityType.Email -> { + Log.d(LogTag("mParticle"), "Setting customer email ${it.value}") + Apptentive.setPersonEmail(it.value) + } else -> Log.d(LogTag("mParticle"), "Other identity type") } } @@ -243,6 +258,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi /* Apptentive SDK does not provide a function which accepts Object as custom data so we need to cast */ private fun addCustomPersonData(key: String, value: String) { // original key + Log.d(LogTag("mParticle"), "Adding custom person data $key to $value") Apptentive.addCustomPersonData(key, value) // typed key @@ -258,7 +274,10 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi Apptentive.addCustomPersonData(key + SUFFIX_KEY_NUMBER, typedValue) } else -> { - Log.e(LogTag("mParticle"),"Unexpected custom person data type:${typedValue?.javaClass}") + Log.e( + LogTag("mParticle"), + "Unexpected custom person data type:${typedValue?.javaClass}" + ) } } } @@ -285,7 +304,10 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi res[key + SUFFIX_KEY_NUMBER] = typedValue } else -> { - Log.e(LogTag("mParticle"),"Unexpected custom data type:${typedValue?.javaClass}") + Log.e( + LogTag("mParticle"), + "Unexpected custom data type:${typedValue?.javaClass}" + ) } } } diff --git a/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt b/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt index 0f012e1..e29d614 100644 --- a/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt +++ b/src/main/kotlin/com/mparticle/kits/CustomDataParser.kt @@ -1,10 +1,13 @@ package com.mparticle.kits -import android.util.Log +import apptentive.com.android.util.InternalUseOnly +import apptentive.com.android.util.Log +import apptentive.com.android.util.LogTag import kotlin.Any import kotlin.Exception import kotlin.String +@OptIn(InternalUseOnly::class) internal object CustomDataParser { fun parseCustomData(map: Map): Map { val res = HashMap() @@ -19,21 +22,19 @@ internal object CustomDataParser { return try { if (value != null) parseValueGuarded(value) else null } catch (e: Exception) { - Log.e("MParticle-Util", "Unable to parse value: $value") + Log.e(LogTag("pParticle"), "Unable to parse value: $value") value } } private fun parseValueGuarded(value: String): Any { // check for boolean - if ("true".equals(value, true) || "false".equals(value,true)) { + if ("true".equals(value, true) || "false".equals(value, true)) { return value.toBoolean() } // check for number val number = StringUtils.tryParseNumber(value) return number ?: value - - // default to the original value } } \ No newline at end of file diff --git a/src/main/kotlin/com/mparticle/kits/StringUtils.kt b/src/main/kotlin/com/mparticle/kits/StringUtils.kt index 404ece3..5adee1d 100644 --- a/src/main/kotlin/com/mparticle/kits/StringUtils.kt +++ b/src/main/kotlin/com/mparticle/kits/StringUtils.kt @@ -20,7 +20,8 @@ internal object StringUtils { } else tryParseDouble(value) } - private fun isInIntegerRange(value: Long): Boolean = value >= Int.MIN_VALUE && value <= Int.MAX_VALUE + private fun isInIntegerRange(value: Long): Boolean = + value >= Int.MIN_VALUE && value <= Int.MAX_VALUE private fun tryParseLong(value: String): Long? { return try { From c51f79a021f93ff1d8ff623b86d2e7765e9124b5 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 28 Feb 2023 14:50:18 -0800 Subject: [PATCH 09/19] Added default values for configuration --- src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index a3ed86d..70dba2a 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -45,6 +45,9 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi configuration.logLevel = getApptentiveLogLevel() configuration.distributionVersion = com.mparticle.BuildConfig.VERSION_NAME configuration.distributionName = "mParticle" + configuration.shouldSanitizeLogMessages = StringUtils.tryParseSettingFlag(settings, SHOULD_SANITIZE_LOG_MESSAGES, true) + configuration.shouldEncryptStorage = StringUtils.tryParseSettingFlag(settings, SHOULD_ENCRYPT_STORAGE, false) + configuration.shouldInheritAppTheme = StringUtils.tryParseSettingFlag(settings, SHOULD_INHERIT_APP_THEME, true) Apptentive.register( context.applicationContext as Application, configuration @@ -322,6 +325,11 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi private const val APPTENTIVE_APP_KEY = "apptentiveAppKey" private const val APPTENTIVE_APP_SIGNATURE = "apptentiveAppSignature" private const val ENABLE_TYPE_DETECTION = "enableTypeDetection" + private const val SHOULD_INHERIT_APP_THEME = "shouldInheritAppTheme" + private const val SHOULD_SANITIZE_LOG_MESSAGES = "shouldSanitizeLogMessages" + private const val SHOULD_ENCRYPT_STORAGE = "shouldEncryptStorage" + private const val RATING_INTERACTION_THROTTLE_LENGTH = "ratingInteractionThrottleLength" + private const val CUSTOM_APP_STORE_URL = "customAppStoreURL" private const val SUFFIX_KEY_FLAG = "_flag" private const val SUFFIX_KEY_NUMBER = "_number" private const val KEY_REQUIRED = From 59ccf2d11e9586f0af4244bdaf2f0ce4d766648e Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 28 Feb 2023 16:30:19 -0800 Subject: [PATCH 10/19] Replaced Apptentive logger with mParticle logger to support tests --- .../com/mparticle/kits/ApptentiveKit.kt | 22 +++++++++---------- .../kotlin/com/mparticle/kits/StringUtils.kt | 13 +++++++++++ .../com/mparticle/kits/ApptentiveKitTest.kt | 6 +++++ .../com/mparticle/kits/StringUtilsTest.kt | 18 +++++++++++++++ 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 70dba2a..7cd1de6 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -6,7 +6,6 @@ import apptentive.com.android.feedback.Apptentive import apptentive.com.android.feedback.ApptentiveConfiguration import apptentive.com.android.feedback.RegisterResult import apptentive.com.android.util.InternalUseOnly -import apptentive.com.android.util.Log import apptentive.com.android.util.LogLevel import apptentive.com.android.util.LogTag import com.mparticle.MPEvent @@ -18,6 +17,7 @@ import com.mparticle.internal.Logger import com.mparticle.kits.KitIntegration.IdentityListener import com.mparticle.kits.KitIntegration.UserAttributeListener import java.util.* +import java.util.concurrent.TimeUnit import kotlin.collections.HashMap @OptIn(InternalUseOnly::class) @@ -48,6 +48,8 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi configuration.shouldSanitizeLogMessages = StringUtils.tryParseSettingFlag(settings, SHOULD_SANITIZE_LOG_MESSAGES, true) configuration.shouldEncryptStorage = StringUtils.tryParseSettingFlag(settings, SHOULD_ENCRYPT_STORAGE, false) configuration.shouldInheritAppTheme = StringUtils.tryParseSettingFlag(settings, SHOULD_INHERIT_APP_THEME, true) + configuration.customAppStoreURL = settings[CUSTOM_APP_STORE_URL] + configuration.ratingInteractionThrottleLength = StringUtils.tryParseLongSettingFlag(settings, RATING_INTERACTION_THROTTLE_LENGTH, TimeUnit.DAYS.toMillis(7)) Apptentive.register( context.applicationContext as Application, configuration @@ -107,7 +109,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi listOfNotNull(lastKnownFirstName, lastKnownLastName).joinToString(separator = " ") .trim() if (fullName.isNotBlank()) { - Log.d(LogTag("mParticle"), "Setting user name $fullName") + Logger.debug( "Setting user name $fullName") Apptentive.setPersonName(fullName) } } @@ -135,7 +137,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi val lastName = userAttribute[MParticle.UserAttributes.LASTNAME] ?: "" val fullName = listOfNotNull(firstName, lastName).joinToString(separator = " ").trim() if (fullName.isNotBlank()) { - Log.d(LogTag("mParticle"), "Setting user name $fullName") + Logger.debug("Setting user name $fullName") Apptentive.setPersonName(fullName) } userAttribute.filterKeys { key -> @@ -241,15 +243,15 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi IdentityType.CustomerId -> { if (KitUtils.isEmpty(Apptentive.getPersonName())) { // Use id as customer name if no full name is set yet. - Log.d(LogTag("mParticle"), "Setting customer id as user name ${it.value}") + Logger.debug("Setting customer id as user name ${it.value}") Apptentive.setPersonName(it.value) } } IdentityType.Email -> { - Log.d(LogTag("mParticle"), "Setting customer email ${it.value}") + Logger.debug("Setting customer email ${it.value}") Apptentive.setPersonEmail(it.value) } - else -> Log.d(LogTag("mParticle"), "Other identity type") + else -> Logger.debug("Other identity type") } } } @@ -261,7 +263,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi /* Apptentive SDK does not provide a function which accepts Object as custom data so we need to cast */ private fun addCustomPersonData(key: String, value: String) { // original key - Log.d(LogTag("mParticle"), "Adding custom person data $key to $value") + Logger.debug("Adding custom person data $key to $value") Apptentive.addCustomPersonData(key, value) // typed key @@ -277,8 +279,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi Apptentive.addCustomPersonData(key + SUFFIX_KEY_NUMBER, typedValue) } else -> { - Log.e( - LogTag("mParticle"), + Logger.error( "Unexpected custom person data type:${typedValue?.javaClass}" ) } @@ -307,8 +308,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi res[key + SUFFIX_KEY_NUMBER] = typedValue } else -> { - Log.e( - LogTag("mParticle"), + Logger.error( "Unexpected custom data type:${typedValue?.javaClass}" ) } diff --git a/src/main/kotlin/com/mparticle/kits/StringUtils.kt b/src/main/kotlin/com/mparticle/kits/StringUtils.kt index 5adee1d..a722cc4 100644 --- a/src/main/kotlin/com/mparticle/kits/StringUtils.kt +++ b/src/main/kotlin/com/mparticle/kits/StringUtils.kt @@ -11,6 +11,19 @@ internal object StringUtils { return value?.toBoolean() ?: defaultValue } + fun tryParseLongSettingFlag( + settings: Map, + key: String?, + defaultValue: Long + ): Long { + val value = settings[key] + return try { + value?.toLong() ?: defaultValue + } catch (e: NumberFormatException) { + defaultValue + } + } + @JvmStatic fun tryParseNumber(value: String): Number? { val longValue = tryParseLong(value) diff --git a/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt b/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt index 68f404c..56ec77d 100644 --- a/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt +++ b/src/test/kotlin/com/mparticle/kits/ApptentiveKitTest.kt @@ -1,7 +1,11 @@ package com.mparticle.kits import android.content.Context +import apptentive.com.android.core.Logger import apptentive.com.android.feedback.Apptentive +import apptentive.com.android.util.InternalUseOnly +import apptentive.com.android.util.Log +import apptentive.com.android.util.LogTag import com.mparticle.MParticle import io.mockk.every import io.mockk.mockk @@ -71,11 +75,13 @@ class ApptentiveKitTest { verify { Apptentive.setPersonName("Doe") } } + @OptIn(InternalUseOnly::class) @Test fun testFirstNameValueOnSetUserAttribute() { val user = mockk() mockkStatic(Apptentive::class) every { Apptentive.setPersonName(any()) } returns Unit + val key = MParticle.UserAttributes.FIRSTNAME val value = "John" diff --git a/src/test/kotlin/com/mparticle/kits/StringUtilsTest.kt b/src/test/kotlin/com/mparticle/kits/StringUtilsTest.kt index b36bc78..3b8385b 100644 --- a/src/test/kotlin/com/mparticle/kits/StringUtilsTest.kt +++ b/src/test/kotlin/com/mparticle/kits/StringUtilsTest.kt @@ -1,10 +1,12 @@ package com.mparticle.kits +import com.mparticle.kits.StringUtils.tryParseLongSettingFlag import com.mparticle.kits.StringUtils.tryParseNumber import com.mparticle.kits.StringUtils.tryParseSettingFlag import org.junit.Assert import org.junit.Test import java.util.HashMap +import java.util.concurrent.TimeUnit class StringUtilsTest { @Test @@ -29,6 +31,22 @@ class StringUtilsTest { Assert.assertTrue(tryParseSettingFlag(data, "key", false)) } + @Test + fun testLongSettingFlag() { + //key is not available + var data= mapOf() + val default = TimeUnit.DAYS.toMillis(7) + Assert.assertEquals(default, tryParseLongSettingFlag(data, "key",default)) + + //key with a long value + data = mapOf("key" to "500") + Assert.assertEquals(500L, tryParseLongSettingFlag(data, "key", default)) + + //key with a invalid type + data = mapOf("key" to "value") + Assert.assertEquals(default, tryParseLongSettingFlag(data, "key", default)) + } + @Test fun testMissingSettingsFlag() { val data= HashMap() From ab59bc84bcd946cf409a5a823462258ddb98d99e Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 28 Feb 2023 16:35:54 -0800 Subject: [PATCH 11/19] cleanup --- build.gradle | 4 ---- .../com/mparticle/kits/ApptentiveKit.kt | 21 ++++++++++++------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index 6c2be3d..cdd5eea 100644 --- a/build.gradle +++ b/build.gradle @@ -7,9 +7,6 @@ buildscript { repositories { google() mavenCentral() - maven { - url "https://apptentive.jfrog.io/artifactory/NewAndroidSDK" - } } dependencies { @@ -22,7 +19,6 @@ buildscript { plugins { id "org.sonarqube" version "3.5.0.2730" id "org.jlleitschuh.gradle.ktlint" version "11.1.0" - id 'org.gradle.maven-publish' } sonarqube { diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 7cd1de6..62e95bf 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -7,7 +7,6 @@ import apptentive.com.android.feedback.ApptentiveConfiguration import apptentive.com.android.feedback.RegisterResult import apptentive.com.android.util.InternalUseOnly import apptentive.com.android.util.LogLevel -import apptentive.com.android.util.LogTag import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType @@ -45,11 +44,18 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi configuration.logLevel = getApptentiveLogLevel() configuration.distributionVersion = com.mparticle.BuildConfig.VERSION_NAME configuration.distributionName = "mParticle" - configuration.shouldSanitizeLogMessages = StringUtils.tryParseSettingFlag(settings, SHOULD_SANITIZE_LOG_MESSAGES, true) - configuration.shouldEncryptStorage = StringUtils.tryParseSettingFlag(settings, SHOULD_ENCRYPT_STORAGE, false) - configuration.shouldInheritAppTheme = StringUtils.tryParseSettingFlag(settings, SHOULD_INHERIT_APP_THEME, true) + configuration.shouldSanitizeLogMessages = + StringUtils.tryParseSettingFlag(settings, SHOULD_SANITIZE_LOG_MESSAGES, true) + configuration.shouldEncryptStorage = + StringUtils.tryParseSettingFlag(settings, SHOULD_ENCRYPT_STORAGE, false) + configuration.shouldInheritAppTheme = + StringUtils.tryParseSettingFlag(settings, SHOULD_INHERIT_APP_THEME, true) configuration.customAppStoreURL = settings[CUSTOM_APP_STORE_URL] - configuration.ratingInteractionThrottleLength = StringUtils.tryParseLongSettingFlag(settings, RATING_INTERACTION_THROTTLE_LENGTH, TimeUnit.DAYS.toMillis(7)) + configuration.ratingInteractionThrottleLength = StringUtils.tryParseLongSettingFlag( + settings, + RATING_INTERACTION_THROTTLE_LENGTH, + TimeUnit.DAYS.toMillis(7) + ) Apptentive.register( context.applicationContext as Application, configuration @@ -65,6 +71,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi override fun setOptOut(optedOut: Boolean): List = emptyList() override fun supportsAttributeLists(): Boolean = false + override fun onConsentStateUpdated( oldState: ConsentState?, newState: ConsentState?, @@ -109,7 +116,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi listOfNotNull(lastKnownFirstName, lastKnownLastName).joinToString(separator = " ") .trim() if (fullName.isNotBlank()) { - Logger.debug( "Setting user name $fullName") + Logger.debug("Setting user name $fullName") Apptentive.setPersonName(fullName) } } @@ -251,7 +258,7 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi Logger.debug("Setting customer email ${it.value}") Apptentive.setPersonEmail(it.value) } - else -> Logger.debug("Other identity type") + else -> Logger.debug("Other identity type") } } } From 1776f159d4044b56a448973711ba62d6ffe09937 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Thu, 2 Mar 2023 15:07:43 -0800 Subject: [PATCH 12/19] reorder loglevel --- src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt index 62e95bf..a375dcf 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKit.kt @@ -234,11 +234,11 @@ class ApptentiveKit : KitIntegration(), KitIntegration.EventListener, IdentityLi //region Helpers private fun getApptentiveLogLevel(): LogLevel { return when (Logger.getMinLogLevel()) { + MParticle.LogLevel.VERBOSE -> LogLevel.Verbose MParticle.LogLevel.DEBUG -> LogLevel.Debug MParticle.LogLevel.INFO -> LogLevel.Info - MParticle.LogLevel.ERROR -> LogLevel.Error MParticle.LogLevel.WARNING -> LogLevel.Warning - MParticle.LogLevel.VERBOSE -> LogLevel.Verbose + MParticle.LogLevel.ERROR -> LogLevel.Error MParticle.LogLevel.NONE -> LogLevel.Info null -> LogLevel.Info } From 94fca31d9f4b52468ccb2b02f27b10c8bd521366 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Fri, 3 Mar 2023 12:44:50 -0800 Subject: [PATCH 13/19] make registerApptentiveActivityContext as static for Java interoperable --- src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt index 6e2d14a..71fc68a 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt @@ -10,6 +10,7 @@ import com.mparticle.MParticle object ApptentiveKitUtils { + @JvmStatic fun registerApptentiveActivityContext(callback: ApptentiveActivityInfo) { if (MParticle.getInstance()?.isKitActive(MParticle.ServiceProviders.APPTENTIVE) == true) { Apptentive.registerApptentiveActivityInfoCallback(callback) From 5755ecefb264cb6b3d69fcb700087a0109df1344 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Mon, 6 Mar 2023 09:53:59 -0800 Subject: [PATCH 14/19] Updated Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75949b4..10533d8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repository contains the [Apptentive](https://www.apptentive.com/) integrati ```groovy dependencies { - implementation 'com.mparticle:android-apptentive-kit:5+' + implementation 'com.mparticle:android-apptentive-kit:6+' } ``` 2. Follow the mParticle Android SDK [quick-start](https://github.com/mParticle/mparticle-android-sdk), then rebuild and launch your app, and verify that you see `"Apptentive detected"` in the output of `adb logcat`. From f10749026e383f4f4236748eacc7a9b263ea9aa5 Mon Sep 17 00:00:00 2001 From: Mo Mustafa <96316894+mmustafa-tse@users.noreply.github.com> Date: Mon, 24 Jul 2023 10:40:57 -0700 Subject: [PATCH 15/19] fix:Apptentive SDK to be used via mParticle (#85) Co-authored-by: markvdouw --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index dfbcb3e..1e2af8d 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,6 @@ allprojects { } dependencies { - implementation 'com.apptentive:apptentive-kit-android:6.0.3' + api 'com.apptentive:apptentive-kit-android:6.0.3' testImplementation 'io.mockk:mockk:1.13.3' } From a650c5dd3cd2928b64f6743192161253dec8b81f Mon Sep 17 00:00:00 2001 From: Chase Date: Mon, 24 Jul 2023 14:10:54 -0400 Subject: [PATCH 16/19] Apptentive 6.1.0 release update --- build.gradle | 2 +- src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d6e769a..09ce68c 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,6 @@ allprojects { } dependencies { - implementation 'com.apptentive:apptentive-kit-android:6.0.3' + implementation 'com.apptentive:apptentive-kit-android:6.1.0' testImplementation 'io.mockk:mockk:1.13.3' } diff --git a/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt b/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt index 71fc68a..c18f3ac 100644 --- a/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt +++ b/src/main/kotlin/com/mparticle/kits/ApptentiveKitUtils.kt @@ -17,7 +17,7 @@ object ApptentiveKitUtils { } else { val filter = IntentFilter(MParticle.ServiceProviders.BROADCAST_ACTIVE + MParticle.ServiceProviders.APPTENTIVE); - callback.getApptentiveActivityInfo().registerReceiver(object : BroadcastReceiver() { + callback.getApptentiveActivityInfo()?.registerReceiver(object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { if (intent.action?.startsWith(MParticle.ServiceProviders.BROADCAST_ACTIVE) == true) { Apptentive.registerApptentiveActivityInfoCallback(callback) From 49be090597afcf8027f7845e93d4a0f9d9281abd Mon Sep 17 00:00:00 2001 From: Chase Date: Tue, 22 Aug 2023 10:46:29 -0400 Subject: [PATCH 17/19] Revert implementation to api Fix readme --- README.md | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 10533d8..75949b4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repository contains the [Apptentive](https://www.apptentive.com/) integrati ```groovy dependencies { - implementation 'com.mparticle:android-apptentive-kit:6+' + implementation 'com.mparticle:android-apptentive-kit:5+' } ``` 2. Follow the mParticle Android SDK [quick-start](https://github.com/mParticle/mparticle-android-sdk), then rebuild and launch your app, and verify that you see `"Apptentive detected"` in the output of `adb logcat`. diff --git a/build.gradle b/build.gradle index 09ce68c..354a163 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,6 @@ allprojects { } dependencies { - implementation 'com.apptentive:apptentive-kit-android:6.1.0' + api 'com.apptentive:apptentive-kit-android:6.1.0' testImplementation 'io.mockk:mockk:1.13.3' } From 0bae122f42a8e48b606ed92b4943a60bde9274d8 Mon Sep 17 00:00:00 2001 From: Poornima Nagarajan Date: Tue, 23 Apr 2024 15:08:19 -0700 Subject: [PATCH 18/19] bumped the version to 6.7.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 354a163..b028ccf 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,6 @@ allprojects { } dependencies { - api 'com.apptentive:apptentive-kit-android:6.1.0' + api 'com.apptentive:apptentive-kit-android:6.7.0' testImplementation 'io.mockk:mockk:1.13.3' } From 79b1ca4cfcd9c5a71804e7def76e1ff8666401fd Mon Sep 17 00:00:00 2001 From: PoornimaApptentive <85186738+PoornimaApptentive@users.noreply.github.com> Date: Thu, 9 May 2024 08:24:07 -0700 Subject: [PATCH 19/19] Update build.gradle re-add mavenLocal() --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index b028ccf..e58ade8 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { repositories { google() + mavenLocal() mavenCentral() }