Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare ParselyTracker for Kotlin migration #98

Merged
merged 9 commits into from
Dec 13, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.parsely.parselyandroid
import android.content.Context
import android.provider.Settings
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.parsely.parselyandroid.Logging.log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

Expand All @@ -18,7 +19,7 @@ internal class AdvertisementIdProvider(
try {
adKey = AdvertisingIdClient.getAdvertisingIdInfo(context).id
} catch (e: Exception) {
ParselyTracker.PLog("No Google play services or error!")
log("No Google play services or error!")
}
}
}
Expand All @@ -40,7 +41,7 @@ internal class AndroidIdProvider(private val context: Context) : IdProvider {
} catch (ex: Exception) {
null
}
ParselyTracker.PLog(String.format("Android ID: %s", uuid))
log(String.format("Android ID: %s", uuid))
return uuid
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.parsely.parselyandroid

import android.content.Context
import android.net.ConnectivityManager

internal interface ConnectivityStatusProvider {
/**
* @return Whether the network is accessible.
*/
fun isReachable(): Boolean
}

internal class AndroidConnectivityStatusProvider(private val context: Context): ConnectivityStatusProvider {

override fun isReachable(): Boolean {
val cm = context.getSystemService(
Context.CONNECTIVITY_SERVICE
) as ConnectivityManager
val netInfo = cm.activeNetworkInfo
return netInfo != null && netInfo.isConnectedOrConnecting
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.parsely.parselyandroid

import android.os.Build
import com.parsely.parselyandroid.Logging.log

internal interface DeviceInfoRepository{
fun collectDeviceInfo(): Map<String, String>
Expand Down Expand Up @@ -34,12 +35,12 @@ internal open class AndroidDeviceInfoRepository(
val adKey = advertisementIdProvider.provide()
val androidId = androidIdProvider.provide()

ParselyTracker.PLog("adkey is: %s, uuid is %s", adKey, androidId)
log("adkey is: %s, uuid is %s", adKey, androidId)

return if (adKey != null) {
adKey
} else {
ParselyTracker.PLog("falling back to device uuid")
log("falling back to device uuid")
androidId .orEmpty()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.parsely.parselyandroid

import kotlin.time.Duration
import com.parsely.parselyandroid.Logging.log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
Expand Down Expand Up @@ -62,7 +62,7 @@ internal class EngagementManager(
val event: MutableMap<String, Any> = HashMap(
baseEvent
)
ParselyTracker.PLog(String.format("Enqueuing %s event.", event["action"]))
log(String.format("Enqueuing %s event.", event["action"]))

// Update `ts` for the event since it's happening right now.
val baseEventData = (event["data"] as Map<String, Any>?)!!
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.parsely.parselyandroid;

import static com.parsely.parselyandroid.ParselyTracker.PLog;

import android.content.Context;
import static com.parsely.parselyandroid.Logging.log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -44,7 +42,7 @@ Map<String, Object> buildEvent(
Map<String, Object> extraData,
@Nullable String uuid
) {
PLog("buildEvent called for %s/%s", action, url);
log("buildEvent called for %s/%s", action, url);

Calendar now = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Expand Down
22 changes: 14 additions & 8 deletions parsely/src/main/java/com/parsely/parselyandroid/FlushQueue.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.parsely.parselyandroid

import com.parsely.parselyandroid.JsonSerializer.toParselyEventsPayload
import com.parsely.parselyandroid.Logging.log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
Expand All @@ -10,12 +11,17 @@ internal class FlushQueue(
private val flushManager: FlushManager,
private val repository: QueueRepository,
private val restClient: RestClient,
private val scope: CoroutineScope
private val scope: CoroutineScope,
private val connectivityStatusProvider: ConnectivityStatusProvider
) {

private val mutex = Mutex()

operator fun invoke(skipSendingEvents: Boolean) {
if (!connectivityStatusProvider.isReachable()) {
log("Network unreachable. Not flushing.")
return
}
scope.launch {
mutex.withLock {
val eventsToSend = repository.getStoredQueue()
Expand All @@ -26,23 +32,23 @@ internal class FlushQueue(
}

if (skipSendingEvents) {
ParselyTracker.PLog("Debug mode on. Not sending to Parse.ly. Otherwise, would sent ${eventsToSend.size} events")
log("Debug mode on. Not sending to Parse.ly. Otherwise, would sent ${eventsToSend.size} events")
repository.remove(eventsToSend)
return@launch
}
ParselyTracker.PLog("Sending request with %d events", eventsToSend.size)
log("Sending request with %d events", eventsToSend.size)
val jsonPayload = toParselyEventsPayload(eventsToSend)
ParselyTracker.PLog("POST Data %s", jsonPayload)
ParselyTracker.PLog("Requested %s", ParselyTracker.ROOT_URL)
log("POST Data %s", jsonPayload)
log("Requested %s", ParselyTracker.ROOT_URL)
restClient.send(jsonPayload)
.fold(
onSuccess = {
ParselyTracker.PLog("Pixel request success")
log("Pixel request success")
repository.remove(eventsToSend)
},
onFailure = {
ParselyTracker.PLog("Pixel request exception")
ParselyTracker.PLog(it.toString())
log("Pixel request exception")
log(it.toString())
}
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.parsely.parselyandroid

import com.parsely.parselyandroid.Logging.log
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
Expand All @@ -22,7 +23,7 @@ internal class InMemoryBuffer(
while (isActive) {
mutex.withLock {
if (buffer.isNotEmpty()) {
ParselyTracker.PLog("Persisting ${buffer.size} events")
log("Persisting ${buffer.size} events")
localStorageRepository.insertEvents(buffer)
buffer.clear()
}
Expand All @@ -35,7 +36,7 @@ internal class InMemoryBuffer(
fun add(event: Map<String, Any>) {
coroutineScope.launch {
mutex.withLock {
ParselyTracker.PLog("Event added to buffer")
log("Event added to buffer")
buffer.add(event)
onEventAddedListener()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.parsely.parselyandroid

import android.content.Context
import com.parsely.parselyandroid.Logging.log
import java.io.EOFException
import java.io.FileNotFoundException
import java.io.ObjectInputStream
Expand Down Expand Up @@ -34,7 +35,7 @@ internal class LocalStorageRepository(private val context: Context) : QueueRepos
oos.close()
fos.close()
} catch (ex: Exception) {
ParselyTracker.PLog("Exception thrown during queue serialization: %s", ex.toString())
log("Exception thrown during queue serialization: %s", ex.toString())
}
}

Expand All @@ -52,7 +53,7 @@ internal class LocalStorageRepository(private val context: Context) : QueueRepos
} catch (ex: FileNotFoundException) {
// Nothing to do here. Means there was no saved queue.
} catch (ex: Exception) {
ParselyTracker.PLog(
log(
"Exception thrown during queue deserialization: %s",
ex.toString()
)
Expand Down
17 changes: 17 additions & 0 deletions parsely/src/main/java/com/parsely/parselyandroid/Logging.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.parsely.parselyandroid

import java.util.Formatter

object Logging {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this moment I can't make this object internal because it won't be visible for Java classes. When the migration from Java to Kotlin is completed, I'll make sure to make it internal.


/**
* Log a message to the console.
*/
@JvmStatic
fun log(logString: String, vararg objects: Any?) {
if (logString == "") {
return
}
println(Formatter().format("[Parsely] $logString", *objects).toString())
}
}
Loading