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

feat: update android storage #15

Merged
merged 7 commits into from
Mar 26, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions android/src/main/java/com/amplitude/android/Configuration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package com.amplitude.android

import android.content.Context
import com.amplitude.android.utilities.AndroidLoggerProvider
import com.amplitude.android.utilities.AndroidStorageProvider
import com.amplitude.core.Configuration
import com.amplitude.core.EventCallBack
import com.amplitude.core.LoggerProvider
import com.amplitude.core.ServerZone
import com.amplitude.core.StorageProvider
import com.amplitude.core.utilities.FileStorageProvider

class Configuration(
apiKey: String,
Expand All @@ -16,7 +16,7 @@ class Configuration(
flushIntervalMillis: Int = FLUSH_INTERVAL_MILLIS,
instanceName: String = DEFAULT_INSTANCE,
optOut: Boolean = false,
storageProvider: StorageProvider = FileStorageProvider(),
storageProvider: StorageProvider = AndroidStorageProvider(),
loggerProvider: LoggerProvider = AndroidLoggerProvider(),
minIdLength: Int? = null,
partnerId: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.amplitude.common.android.AndroidContextProvider
import com.amplitude.core.Amplitude
import com.amplitude.core.events.BaseEvent
import com.amplitude.core.platform.Plugin
import java.util.UUID

class AndroidContextPlugin : Plugin {
override val type: Plugin.Type = Plugin.Type.Before
Expand Down Expand Up @@ -49,9 +50,21 @@ class AndroidContextPlugin : Plugin {

private fun applyContextData(event: BaseEvent) {
val configuration = amplitude.configuration as Configuration
event.library = "$SDK_LIBRARY/$SDK_VERSION"
event.userId = amplitude.store.userId
event.deviceId = amplitude.store.deviceId
event.timestamp ?: let {
event.timestamp = System.currentTimeMillis()
}
event.insertId ?: let {
event.insertId = UUID.randomUUID().toString()
}
event.library ?: let {
event.library = "$SDK_LIBRARY/$SDK_VERSION"
}
event.userId ?: let {
event.userId = amplitude.store.userId
}
event.deviceId ?: let {
event.deviceId = amplitude.store.deviceId
}
event.sessionId = (amplitude as com.amplitude.android.Amplitude).sessionId
val trackingOptions = configuration.trackingOptions
if (configuration.enableCoppaControl) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.amplitude.android.utilities

import android.content.SharedPreferences
import com.amplitude.id.utilities.KeyValueStore

class AndroidKVS(private val sharedPreferences: SharedPreferences) : KeyValueStore {
override fun getLong(key: String, defaultVal: Long): Long {
return sharedPreferences.getLong(key, defaultVal)
}

override fun putLong(key: String, value: Long): Boolean {
return sharedPreferences.edit().putLong(key, value).commit()
}
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,112 @@
package com.amplitude.android.utilities

import android.content.Context
import android.content.SharedPreferences
import com.amplitude.core.Amplitude
import com.amplitude.core.Configuration
import com.amplitude.core.EventCallBack
import com.amplitude.core.Storage
import com.amplitude.core.StorageProvider
import com.amplitude.core.events.BaseEvent
import com.amplitude.core.platform.EventPipeline
import com.amplitude.core.utilities.EventsFileManager
import com.amplitude.core.utilities.EventsFileStorage
import com.amplitude.core.utilities.FileResponseHandler
import com.amplitude.core.utilities.JSONUtil
import com.amplitude.core.utilities.ResponseHandler
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import org.json.JSONArray
import java.io.BufferedReader
import java.io.File

class AndroidStorage(
val amplitude: Amplitude
) : Storage {
context: Context,
apiKey: String
) : Storage, EventsFileStorage {

companion object {
const val STORAGE_PREFIX = "amplitude-android"
}

private val sharedPreferences: SharedPreferences =
context.getSharedPreferences("${ STORAGE_PREFIX}-$apiKey", Context.MODE_PRIVATE)
qingzhuozhen marked this conversation as resolved.
Show resolved Hide resolved
private val storageDirectory: File = context.getDir("segment-disk-queue", Context.MODE_PRIVATE)
qingzhuozhen marked this conversation as resolved.
Show resolved Hide resolved
private val eventsFile =
EventsFileManager(storageDirectory, apiKey, AndroidKVS(sharedPreferences))
private val eventCallbacksMap = mutableMapOf<String, EventCallBack>()

override suspend fun writeEvent(event: BaseEvent) {
TODO("Not yet implemented")
eventsFile.storeEvent(JSONUtil.eventToString(event))
event.callback?.let { callback ->
event.insertId?. let {
eventCallbacksMap.put(it, callback)
}
}
}

override suspend fun write(key: Storage.Constants, value: String) {
TODO("Not yet implemented")
sharedPreferences.edit().putString(key.rawVal, value).apply()
}

override suspend fun rollover() {
TODO("Not yet implemented")
eventsFile.rollover()
}

override fun read(key: Storage.Constants): String? {
TODO("Not yet implemented")
return sharedPreferences.getString(key.rawVal, null)
}

override fun readEventsContent(): List<Any> {
TODO("Not yet implemented")
return eventsFile.read()
}

override fun getEventsString(content: Any): String {
TODO("Not yet implemented")
val bufferedReader: BufferedReader = File(content as String).bufferedReader()
bufferedReader.use {
return it.readText()
}
}

override fun getResponseHandler(
storage: Storage,
eventPipeline: EventPipeline,
configuration: Configuration,
scope: CoroutineScope,
dispatcher: CoroutineDispatcher,
events: Any,
eventsString: String
): ResponseHandler {
TODO("Not yet implemented")
return FileResponseHandler(
this,
eventPipeline,
configuration,
scope,
dispatcher,
events as String,
eventsString
)
}

override fun removeFile(filePath: String): Boolean {
return eventsFile.remove(filePath)
}

override fun getEventCallback(insertId: String): EventCallBack? {
return eventCallbacksMap.getOrDefault(insertId, null)
}

override fun removeEventCallback(insertId: String) {
eventCallbacksMap.remove(insertId)
}

override fun splitEventFile(filePath: String, events: JSONArray) {
eventsFile.splitFile(filePath, events)
}
}

class AndroidStorageProvider : StorageProvider {
override fun getStorage(amplitude: Amplitude): Storage {
return AndroidStorage(amplitude)
val configuration = amplitude.configuration as com.amplitude.android.Configuration
return AndroidStorage(configuration.context, configuration.apiKey)
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/com/amplitude/core/Storage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ interface Storage {

fun getEventsString(content: Any): String

fun getResponseHandler(storage: Storage, eventPipeline: EventPipeline, configuration: Configuration, scope: CoroutineScope, dispatcher: CoroutineDispatcher, events: Any, eventsString: String): ResponseHandler
fun getResponseHandler(eventPipeline: EventPipeline, configuration: Configuration, scope: CoroutineScope, dispatcher: CoroutineDispatcher, events: Any, eventsString: String): ResponseHandler
}

interface StorageProvider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class EventPipeline(
// Upload the payloads.
connection.close()
}
val responseHandler = storage.getResponseHandler(storage, this@EventPipeline, amplitude.configuration, scope, amplitude.retryDispatcher, events, eventsString)
val responseHandler = storage.getResponseHandler(this@EventPipeline, amplitude.configuration, scope, amplitude.retryDispatcher, events, eventsString)
responseHandler?.handle(connection.response)
} catch (e: Exception) {
e.message?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@ class ContextPlugin : Plugin {
}

private fun applyContextData(event: BaseEvent) {
event.timestamp ?: run {
event.timestamp ?: let {
event.timestamp = System.currentTimeMillis()
}
event.insertId ?: run {
event.insertId ?: let {
event.insertId = UUID.randomUUID().toString()
}
event.library = Constants.SDK_LIBRARY + "/" + Constants.SDK_VERSION
event.userId = amplitude.store.userId
event.deviceId = amplitude.store.deviceId
event.library ?: let {
event.library = "${Constants.SDK_LIBRARY}/${Constants.SDK_VERSION}"
}
event.userId ?: let {
event.userId = amplitude.store.userId
}
event.deviceId ?: let {
event.deviceId = amplitude.store.deviceId
}
event.partnerId ?: let {
amplitude.configuration.partnerId ?. let {
event.partnerId = it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.json.JSONArray

internal class FileResponseHandler(
private val storage: FileStorage,
class FileResponseHandler(
private val storage: EventsFileStorage,
private val eventPipeline: EventPipeline,
private val configuration: Configuration,
private val scope: CoroutineScope,
Expand Down
23 changes: 16 additions & 7 deletions core/src/main/java/com/amplitude/core/utilities/FileStorage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import java.io.File

class FileStorage(
private val apiKey: String
) : Storage {
) : Storage, EventsFileStorage {

companion object {
const val STORAGE_PREFIX = "amplitude-kotlin"
Expand Down Expand Up @@ -68,7 +68,6 @@ class FileStorage(
}

override fun getResponseHandler(
storage: Storage,
eventPipeline: EventPipeline,
configuration: Configuration,
scope: CoroutineScope,
Expand All @@ -77,7 +76,7 @@ class FileStorage(
eventsString: String
): ResponseHandler {
return FileResponseHandler(
storage as FileStorage,
this,
eventPipeline,
configuration,
scope,
Expand All @@ -87,19 +86,19 @@ class FileStorage(
)
}

fun removeFile(filePath: String): Boolean {
override fun removeFile(filePath: String): Boolean {
return eventsFile.remove(filePath)
}

fun getEventCallback(insertId: String): EventCallBack? {
override fun getEventCallback(insertId: String): EventCallBack? {
return eventCallbacksMap.getOrDefault(insertId, null)
}

fun removeEventCallback(insertId: String) {
override fun removeEventCallback(insertId: String) {
eventCallbacksMap.remove(insertId)
}

fun splitEventFile(filePath: String, events: JSONArray) {
override fun splitEventFile(filePath: String, events: JSONArray) {
eventsFile.splitFile(filePath, events)
}
}
Expand All @@ -109,3 +108,13 @@ class FileStorageProvider : StorageProvider {
return FileStorage(amplitude.configuration.apiKey)
}
}

interface EventsFileStorage {
fun removeFile(filePath: String): Boolean

fun getEventCallback(insertId: String): EventCallBack?

fun removeEventCallback(insertId: String)

fun splitEventFile(filePath: String, events: JSONArray)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ class InMemoryStorage(
}

override fun read(key: Storage.Constants): String? {
return valuesMap.getOrDefault(key.rawVal, null)
if (!valuesMap.contains(key.rawVal)) {
return null
}
return valuesMap.get(key.rawVal)
}

override fun readEventsContent(): List<Any> {
Expand All @@ -51,7 +54,6 @@ class InMemoryStorage(
}

override fun getResponseHandler(
storage: Storage,
eventPipeline: EventPipeline,
configuration: Configuration,
scope: CoroutineScope,
Expand Down