@@ -10,162 +10,162 @@ import org.json.JSONObject
1010
1111internal abstract class ChannelTracker internal constructor(protected var dataRepository : InfluenceDataRepository , private var timeProvider : ITime ) :
1212 IChannelTracker {
13- override var influenceType: InfluenceType ? = null
14- override var indirectIds: JSONArray ? = null
15- override var directId: String? = null
13+ override var influenceType: InfluenceType ? = null
14+ override var indirectIds: JSONArray ? = null
15+ override var directId: String? = null
1616
17- @get:Throws(JSONException ::class )
18- abstract val lastChannelObjects: JSONArray
19- abstract val channelLimit: Int
20- abstract val indirectAttributionWindow: Int
17+ @get:Throws(JSONException ::class )
18+ abstract val lastChannelObjects: JSONArray
19+ abstract val channelLimit: Int
20+ abstract val indirectAttributionWindow: Int
2121
22- abstract fun getLastChannelObjectsReceivedByNewId (id : String? ): JSONArray
22+ abstract fun getLastChannelObjectsReceivedByNewId (id : String? ): JSONArray
2323
24- abstract fun saveChannelObjects (channelObjects : JSONArray )
24+ abstract fun saveChannelObjects (channelObjects : JSONArray )
2525
26- abstract fun initInfluencedTypeFromCache ()
26+ abstract fun initInfluencedTypeFromCache ()
2727
28- private val isDirectSessionEnabled: Boolean
29- get() = dataRepository.isDirectInfluenceEnabled
28+ private val isDirectSessionEnabled: Boolean
29+ get() = dataRepository.isDirectInfluenceEnabled
3030
31- private val isIndirectSessionEnabled: Boolean
32- get() = dataRepository.isIndirectInfluenceEnabled
31+ private val isIndirectSessionEnabled: Boolean
32+ get() = dataRepository.isIndirectInfluenceEnabled
3333
34- private val isUnattributedSessionEnabled: Boolean
35- get() = dataRepository.isUnattributedInfluenceEnabled
34+ private val isUnattributedSessionEnabled: Boolean
35+ get() = dataRepository.isUnattributedInfluenceEnabled
3636
37- /* *
38- * Get the current session based on state + if outcomes features are enabled.
39- */
40- override val currentSessionInfluence: Influence
41- get() {
42- val sessionInfluence = Influence (channelType, InfluenceType .DISABLED , null )
43- // Channel weren't init yet because application is starting
44- if (influenceType == null ) initInfluencedTypeFromCache()
37+ /* *
38+ * Get the current session based on state + if outcomes features are enabled.
39+ */
40+ override val currentSessionInfluence: Influence
41+ get() {
42+ val sessionInfluence = Influence (channelType, InfluenceType .DISABLED , null )
43+ // Channel weren't init yet because application is starting
44+ if (influenceType == null ) initInfluencedTypeFromCache()
4545
46- val currentInfluenceType = influenceType ? : InfluenceType .DISABLED
46+ val currentInfluenceType = influenceType ? : InfluenceType .DISABLED
4747
48- if (currentInfluenceType.isDirect()) {
49- if (isDirectSessionEnabled) {
50- sessionInfluence.apply {
51- ids = JSONArray ().put(this @ChannelTracker.directId)
52- influenceType = InfluenceType .DIRECT
53- }
54- }
55- } else if (currentInfluenceType.isIndirect()) {
56- if (isIndirectSessionEnabled) {
57- sessionInfluence.apply {
58- ids = this @ChannelTracker.indirectIds
59- influenceType = InfluenceType .INDIRECT
60- }
61- }
62- } else if (isUnattributedSessionEnabled) {
48+ if (currentInfluenceType.isDirect()) {
49+ if (isDirectSessionEnabled) {
6350 sessionInfluence.apply {
64- influenceType = InfluenceType .UNATTRIBUTED
51+ ids = JSONArray ().put(this @ChannelTracker.directId)
52+ influenceType = InfluenceType .DIRECT
6553 }
6654 }
67-
68- return sessionInfluence
69- }
70-
71- /* *
72- * Get all received ids that may influence actions
73- * @return ids that happen between attribution window
74- */
75- override val lastReceivedIds: JSONArray
76- get() {
77- val ids = JSONArray ()
78- try {
79- val lastChannelObjectReceived = lastChannelObjects
80- Logging .debug(" ChannelTracker.getLastReceivedIds: lastChannelObjectReceived: $lastChannelObjectReceived " )
81- val attributionWindow = indirectAttributionWindow * 60 * 1000L
82- val currentTime = timeProvider.currentTimeMillis
83- for (i in 0 until lastChannelObjectReceived.length()) {
84- val jsonObject = lastChannelObjectReceived.getJSONObject(i)
85- val time = jsonObject.getLong(InfluenceConstants .TIME )
86- val difference = currentTime - time
87- if (difference <= attributionWindow) {
88- val id = jsonObject.getString(idTag)
89- ids.put(id)
90- }
55+ } else if (currentInfluenceType.isIndirect()) {
56+ if (isIndirectSessionEnabled) {
57+ sessionInfluence.apply {
58+ ids = this @ChannelTracker.indirectIds
59+ influenceType = InfluenceType .INDIRECT
9160 }
92- } catch (exception: JSONException ) {
93- Logging .error(" ChannelTracker.getLastReceivedIds: Generating tracker getLastReceivedIds JSONObject " , exception)
9461 }
95- return ids
62+ } else if (isUnattributedSessionEnabled) {
63+ sessionInfluence.apply {
64+ influenceType = InfluenceType .UNATTRIBUTED
65+ }
9666 }
9767
98- override fun resetAndInitInfluence () {
99- directId = null
100- indirectIds = lastReceivedIds
101- influenceType = if (indirectIds?.length() ? : 0 > 0 ) InfluenceType .INDIRECT else InfluenceType .UNATTRIBUTED
102- cacheState()
103- Logging .debug(" ChannelTracker.resetAndInitInfluence: $idTag finish with influenceType: $influenceType " )
68+ return sessionInfluence
10469 }
10570
106- /* *
107- * Save state of last ids received
108- */
109- override fun saveLastId (id : String? ) {
110- Logging .debug(" ChannelTracker.saveLastId(id: $id ): idTag=$idTag " )
111- if (id == null || id.isEmpty()) return
112-
113- val lastChannelObjectsReceived = getLastChannelObjectsReceivedByNewId(id)
114- Logging .debug(" ChannelTracker.saveLastId: for $idTag saveLastId with lastChannelObjectsReceived: $lastChannelObjectsReceived " )
115-
71+ /* *
72+ * Get all received ids that may influence actions
73+ * @return ids that happen between attribution window
74+ */
75+ override val lastReceivedIds: JSONArray
76+ get() {
77+ val ids = JSONArray ()
11678 try {
117- timeProvider.run {
118- JSONObject ()
119- .put(idTag, id)
120- .put(InfluenceConstants .TIME , currentTimeMillis)
121- }.also { newInfluenceId ->
122- lastChannelObjectsReceived.put(newInfluenceId)
79+ val lastChannelObjectReceived = lastChannelObjects
80+ Logging .debug(" ChannelTracker.getLastReceivedIds: lastChannelObjectReceived: $lastChannelObjectReceived " )
81+ val attributionWindow = indirectAttributionWindow * 60 * 1000L
82+ val currentTime = timeProvider.currentTimeMillis
83+ for (i in 0 until lastChannelObjectReceived.length()) {
84+ val jsonObject = lastChannelObjectReceived.getJSONObject(i)
85+ val time = jsonObject.getLong(InfluenceConstants .TIME )
86+ val difference = currentTime - time
87+ if (difference <= attributionWindow) {
88+ val id = jsonObject.getString(idTag)
89+ ids.put(id)
90+ }
12391 }
12492 } catch (exception: JSONException ) {
125- Logging .error(" ChannelTracker.saveLastId: Generating tracker newInfluenceId JSONObject " , exception)
126- // We don't have new data, stop logic
127- return
93+ Logging .error(" ChannelTracker.getLastReceivedIds: Generating tracker getLastReceivedIds JSONObject " , exception)
12894 }
95+ return ids
96+ }
12997
130- var channelObjectToSave = lastChannelObjectsReceived
131- // Only save the last ids without surpassing the limit
132- // Always keep the max quantity of ids possible
133- // If the attribution window increases, old ids might influence
134- if (lastChannelObjectsReceived.length() > channelLimit) {
135- val lengthDifference = lastChannelObjectsReceived.length() - channelLimit
136- // If min sdk is greater than KITKAT we can refactor this logic to removeObject from JSONArray
137- channelObjectToSave = JSONArray ()
138- for (i in lengthDifference until lastChannelObjectsReceived.length()) {
139- try {
140- channelObjectToSave.put(lastChannelObjectsReceived[i])
141- } catch (exception: JSONException ) {
142- Logging .error(" ChannelTracker.saveLastId: Generating tracker lastChannelObjectsReceived get JSONObject " , exception)
143- }
144- }
98+ override fun resetAndInitInfluence () {
99+ directId = null
100+ indirectIds = lastReceivedIds
101+ influenceType = if (indirectIds?.length() ? : 0 > 0 ) InfluenceType .INDIRECT else InfluenceType .UNATTRIBUTED
102+ cacheState()
103+ Logging .debug(" ChannelTracker.resetAndInitInfluence: $idTag finish with influenceType: $influenceType " )
104+ }
105+
106+ /* *
107+ * Save state of last ids received
108+ */
109+ override fun saveLastId (id : String? ) {
110+ Logging .debug(" ChannelTracker.saveLastId(id: $id ): idTag=$idTag " )
111+ if (id == null || id.isEmpty()) return
112+
113+ val lastChannelObjectsReceived = getLastChannelObjectsReceivedByNewId(id)
114+ Logging .debug(" ChannelTracker.saveLastId: for $idTag saveLastId with lastChannelObjectsReceived: $lastChannelObjectsReceived " )
115+
116+ try {
117+ timeProvider.run {
118+ JSONObject ()
119+ .put(idTag, id)
120+ .put(InfluenceConstants .TIME , currentTimeMillis)
121+ }.also { newInfluenceId ->
122+ lastChannelObjectsReceived.put(newInfluenceId)
145123 }
146- Logging .debug(" ChannelTracker.saveLastId: for $idTag with channelObjectToSave: $channelObjectToSave " )
147- saveChannelObjects(channelObjectToSave)
124+ } catch (exception: JSONException ) {
125+ Logging .error(" ChannelTracker.saveLastId: Generating tracker newInfluenceId JSONObject " , exception)
126+ // We don't have new data, stop logic
127+ return
148128 }
149129
150- override fun toString (): String {
151- return " ChannelTracker{" +
152- " tag=" + idTag +
153- " , influenceType=" + influenceType +
154- " , indirectIds=" + indirectIds +
155- " , directId=" + directId +
156- ' }'
130+ var channelObjectToSave = lastChannelObjectsReceived
131+ // Only save the last ids without surpassing the limit
132+ // Always keep the max quantity of ids possible
133+ // If the attribution window increases, old ids might influence
134+ if (lastChannelObjectsReceived.length() > channelLimit) {
135+ val lengthDifference = lastChannelObjectsReceived.length() - channelLimit
136+ // If min sdk is greater than KITKAT we can refactor this logic to removeObject from JSONArray
137+ channelObjectToSave = JSONArray ()
138+ for (i in lengthDifference until lastChannelObjectsReceived.length()) {
139+ try {
140+ channelObjectToSave.put(lastChannelObjectsReceived[i])
141+ } catch (exception: JSONException ) {
142+ Logging .error(" ChannelTracker.saveLastId: Generating tracker lastChannelObjectsReceived get JSONObject " , exception)
143+ }
144+ }
157145 }
146+ Logging .debug(" ChannelTracker.saveLastId: for $idTag with channelObjectToSave: $channelObjectToSave " )
147+ saveChannelObjects(channelObjectToSave)
148+ }
158149
159- override fun equals (other : Any? ): Boolean {
160- if (this == = other) return true
161- if (other == null || javaClass != other.javaClass) return false
162- val tracker = other as ChannelTracker
163- return influenceType == = tracker.influenceType && tracker.idTag == idTag
164- }
150+ override fun toString (): String {
151+ return " ChannelTracker{" +
152+ " tag=" + idTag +
153+ " , influenceType=" + influenceType +
154+ " , indirectIds=" + indirectIds +
155+ " , directId=" + directId +
156+ ' }'
157+ }
165158
166- override fun hashCode (): Int {
167- var result = influenceType.hashCode()
168- result = 31 * result + idTag.hashCode()
169- return result
170- }
159+ override fun equals (other : Any? ): Boolean {
160+ if (this == = other) return true
161+ if (other == null || javaClass != other.javaClass) return false
162+ val tracker = other as ChannelTracker
163+ return influenceType == = tracker.influenceType && tracker.idTag == idTag
164+ }
165+
166+ override fun hashCode (): Int {
167+ var result = influenceType.hashCode()
168+ result = 31 * result + idTag.hashCode()
169+ return result
171170 }
171+ }
0 commit comments