Skip to content

Commit ff3596b

Browse files
feat: Allow Client to Manually Call Appsflyer Start (#117)
1 parent 541195a commit ff3596b

3 files changed

Lines changed: 99 additions & 82 deletions

File tree

src/main/kotlin/com/mparticle/kits/AppsFlyerKit.kt

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,11 @@ class AppsFlyerKit :
6262
MParticle.getInstance()?.environment == MParticle.Environment.Development,
6363
)
6464
settings[DEV_KEY]?.let { AppsFlyerLib.getInstance().init(it, this, context) }
65-
setting?.get(SHARING_FILTER_FOR_PARTNERS)?.let {
66-
applySharingFilterForPartners(it)
67-
}
6865
val userConsentState = currentUser?.consentState
6966
setConsent(userConsentState)
70-
AppsFlyerLib.getInstance().start(context.applicationContext)
67+
if (!isManualStart()) {
68+
AppsFlyerLib.getInstance().start(context.applicationContext)
69+
}
7170
AppsFlyerLib.getInstance().setCollectAndroidID(MParticle.isAndroidIdEnabled())
7271
val integrationAttributes = HashMap<String, String?>(1)
7372
integrationAttributes[APPSFLYERID_INTEGRATION_KEY] =
@@ -559,7 +558,9 @@ class AppsFlyerKit :
559558
activity: Activity,
560559
bundle: Bundle?,
561560
): List<ReportingMessage> {
562-
instance.start(activity)
561+
if (!isManualStart()) {
562+
instance.start(activity)
563+
}
563564
return emptyList()
564565
}
565566

@@ -578,31 +579,7 @@ class AppsFlyerKit :
578579

579580
override fun onActivityDestroyed(activity: Activity): List<ReportingMessage> = emptyList()
580581

581-
override fun onSettingsUpdated(settings: Map<String, String>) {
582-
settings[SHARING_FILTER_FOR_PARTNERS]?.let { applySharingFilterForPartners(it) }
583-
}
584-
585-
private fun applySharingFilterForPartners(jsonValue: String) {
586-
val partners = parseSharingFilterForPartners(jsonValue)
587-
if (!partners.isNullOrEmpty()) {
588-
instance.setSharingFilterForPartners(*partners.toTypedArray())
589-
}
590-
}
591-
592-
private fun parseSharingFilterForPartners(json: String?): List<String>? {
593-
if (json.isNullOrEmpty()) return null
594-
return try {
595-
val jsonWithFormat = json.replace("\\", "")
596-
val array = JSONArray(jsonWithFormat)
597-
List(array.length()) { i -> array.getString(i) }
598-
} catch (e: JSONException) {
599-
Logger.warning(
600-
"AppsFlyer kit: failed to parse sharingFilterForPartners, " +
601-
"consent filter for partners will not be applied. Error: ${e.message}",
602-
)
603-
null
604-
}
605-
}
582+
private fun isManualStart(): Boolean = settings[MANUAL_START]?.lowercase() == "true"
606583

607584
companion object {
608585
const val DEV_KEY = "devKey"
@@ -630,7 +607,7 @@ class AppsFlyerKit :
630607
}
631608
}
632609

633-
private const val SHARING_FILTER_FOR_PARTNERS = "sharingFilterForPartners"
610+
const val MANUAL_START = "manualStart"
634611
private const val CONSENT_MAPPING = "consentMapping"
635612

636613
@Suppress("ktlint:standard:property-naming")

src/test/kotlin/com/appsflyer/AppsFlyerLib.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,40 @@ import android.content.Context
55
class AppsFlyerLib {
66
private var consentData: AppsFlyerConsent? = null
77

8+
var startCallCount = 0
9+
private set
10+
11+
var customerUserId: String? = null
12+
private set
13+
814
fun setConsentData(consent: AppsFlyerConsent) {
915
consentData = consent
1016
}
1117

1218
fun getConsentData(): AppsFlyerConsent? = consentData
1319

20+
fun start(context: Context) {
21+
startCallCount++
22+
}
23+
24+
fun setCustomerUserId(id: String?) {
25+
customerUserId = id
26+
}
27+
28+
fun init(
29+
devKey: String,
30+
conversionListener: Any?,
31+
context: Context,
32+
) {}
33+
34+
fun setCollectAndroidID(collect: Boolean) {}
35+
36+
fun getAppsFlyerUID(context: Context): String = "test-appsflyer-uid"
37+
38+
fun subscribeForDeepLink(listener: Any?) {}
39+
40+
fun setDebugLog(debug: Boolean) {}
41+
1442
fun getConsentState(): MutableMap<Any, Any> {
1543
val stateMap = mutableMapOf<Any, Any>()
1644
consentData?.let { consent ->

src/test/kotlin/com/mparticle/kits/AppsflyerKitTests.kt

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -76,57 +76,6 @@ class AppsflyerKitTests {
7676
Assert.assertTrue(name.isNotEmpty())
7777
}
7878

79-
@Test
80-
@Throws(Exception::class)
81-
fun testParseSharingFilterForPartners_returnsListForValidJson() {
82-
val method =
83-
AppsFlyerKit::class.java.getDeclaredMethod(
84-
"parseSharingFilterForPartners",
85-
String::class.java,
86-
)
87-
method.isAccessible = true
88-
val result = method.invoke(kit, """["partner_1", "partner_2"]""")
89-
Assert.assertEquals(listOf("partner_1", "partner_2"), result)
90-
}
91-
92-
@Test
93-
@Throws(Exception::class)
94-
fun testParseSharingFilterForPartners_returnsNullForEmptyInput() {
95-
val method =
96-
AppsFlyerKit::class.java.getDeclaredMethod(
97-
"parseSharingFilterForPartners",
98-
String::class.java,
99-
)
100-
method.isAccessible = true
101-
Assert.assertNull(method.invoke(kit, ""))
102-
Assert.assertNull(method.invoke(kit, null))
103-
}
104-
105-
@Test
106-
@Throws(Exception::class)
107-
fun testParseSharingFilterForPartners_returnsNullForInvalidJson() {
108-
val method =
109-
AppsFlyerKit::class.java.getDeclaredMethod(
110-
"parseSharingFilterForPartners",
111-
String::class.java,
112-
)
113-
method.isAccessible = true
114-
Assert.assertNull(method.invoke(kit, "not a json array"))
115-
}
116-
117-
@Test
118-
@Throws(Exception::class)
119-
fun testParseSharingFilterForPartners_stripsBackslashes() {
120-
val method =
121-
AppsFlyerKit::class.java.getDeclaredMethod(
122-
"parseSharingFilterForPartners",
123-
String::class.java,
124-
)
125-
method.isAccessible = true
126-
val result = method.invoke(kit, """[\"test_1\", \"test_2\"]""")
127-
Assert.assertEquals(listOf("test_1", "test_2"), result)
128-
}
129-
13079
/**
13180
* Kit *should* throw an exception when they're initialized with the wrong settings.
13281
*
@@ -776,6 +725,69 @@ class AppsflyerKitTests {
776725
Assert.assertEquals(emptyMap<String, String>(), result)
777726
}
778727

728+
// region manualStart tests
729+
730+
@Test
731+
@Throws(Exception::class)
732+
fun testIsManualStart_returnsTrueWhenSettingIsTrue() {
733+
setKitSettings(mapOf(AppsFlyerKit.MANUAL_START to "true"))
734+
val method = AppsFlyerKit::class.java.getDeclaredMethod("isManualStart")
735+
method.isAccessible = true
736+
Assert.assertTrue(method.invoke(kit) as Boolean)
737+
}
738+
739+
@Test
740+
@Throws(Exception::class)
741+
fun testIsManualStart_returnsFalseWhenSettingIsFalse() {
742+
setKitSettings(mapOf(AppsFlyerKit.MANUAL_START to "false"))
743+
val method = AppsFlyerKit::class.java.getDeclaredMethod("isManualStart")
744+
method.isAccessible = true
745+
Assert.assertFalse(method.invoke(kit) as Boolean)
746+
}
747+
748+
@Test
749+
@Throws(Exception::class)
750+
fun testIsManualStart_returnsFalseWhenSettingIsAbsent() {
751+
setKitSettings(emptyMap())
752+
val method = AppsFlyerKit::class.java.getDeclaredMethod("isManualStart")
753+
method.isAccessible = true
754+
Assert.assertFalse(method.invoke(kit) as Boolean)
755+
}
756+
757+
@Test
758+
@Throws(Exception::class)
759+
fun testOnActivityCreated_withManualStartTrue_doesNotCallStart() {
760+
setKitSettings(
761+
mapOf(
762+
AppsFlyerKit.MANUAL_START to "true",
763+
),
764+
)
765+
kit.onActivityCreated(mock(Activity::class.java), null)
766+
Assert.assertEquals(0, appsflyer.startCallCount)
767+
}
768+
769+
@Test
770+
@Throws(Exception::class)
771+
fun testOnActivityCreated_withManualStartFalse_callsStart() {
772+
setKitSettings(
773+
mapOf(
774+
AppsFlyerKit.MANUAL_START to "false",
775+
),
776+
)
777+
kit.onActivityCreated(mock(Activity::class.java), null)
778+
Assert.assertEquals(1, appsflyer.startCallCount)
779+
}
780+
781+
@Throws(Exception::class)
782+
private fun setKitSettings(settings: Map<String, String>) {
783+
val configJson = JSONObject()
784+
configJson.put("id", "-1")
785+
configJson.put("as", settings.toMutableMap())
786+
kit.configuration = KitConfiguration.createKitConfiguration(configJson)
787+
}
788+
789+
// endregion
790+
779791
private var emptyCoreCallbacks: CoreCallbacks =
780792
object : CoreCallbacks {
781793
var activity = Activity()

0 commit comments

Comments
 (0)