-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
35 changed files
with
1,172 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
*.iml | ||
.gradle | ||
/local.properties | ||
/.idea | ||
.DS_Store | ||
/build | ||
/captures | ||
.externalNativeBuild | ||
.cxx | ||
local.properties |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# KryptoStore | ||
KryptoStore is thin wrapper around Jetpack DataStore Preferences that provides useful features. | ||
|
||
## Features | ||
* Small | ||
* Easily work with primitive preferences | ||
* Serialization for complex objects | ||
* Encryption | ||
|
||
## Basic Usage | ||
Import library: TODO | ||
```kotlin | ||
implementation("TODO") | ||
``` | ||
Use preferences. Supported preferences: booleanPref, intPref, floatPref, doublePref, stringPref, stringSetPref. | ||
```kotlin | ||
val Context.store: DataStore<Preferences> by preferencesDataStore(name = "prefs") | ||
val pref = booleanPref(context.store, "testBoolean", false) | ||
val value = pref.get() | ||
pref.set(true) | ||
``` | ||
|
||
## Advanced Usage | ||
Import library for serialization | ||
```kotlin | ||
implementation("TODO") | ||
``` | ||
Create serialized preferences: | ||
```kotlin | ||
data class TestData(val one: String, val two: Double) | ||
val Context.store: DataStore<Preferences> by preferencesDataStore(name = "prefs") | ||
val pref = gsonPref(context.store, "testGsonPrefData", TestData("Don't Panic", 42.0), Gson()) | ||
val value = pref.get() | ||
pref.set(TestData("Mostly Harmless", 43.0)) | ||
``` | ||
|
||
## Encryption | ||
Import library for encryption | ||
```kotlin | ||
implementation("TODO") | ||
``` | ||
Create encrypted preferences: | ||
```kotlin | ||
data class TestData(val one: String, val two: Double) | ||
val Context.store: DataStore<Preferences> by preferencesDataStore(name = "prefs") | ||
val pref = encryptedKeystorePref(context.store, "testEncryptedPrefData", TestData("Don't Panic", 42.0), createGsonTransform(gson)) | ||
val value = pref.get() | ||
pref.set(TestData("Mostly Harmless", 43.0)) | ||
``` | ||
|
||
## TODO | ||
* More serialization options: Moshi, kotlinx.serialization, etc... | ||
* More encryption options. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
plugins { | ||
id("com.android.application") version "8.3.0" apply false | ||
id("org.jetbrains.kotlin.android") version "1.9.22" apply false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
plugins { | ||
id("com.android.library") | ||
id("org.jetbrains.kotlin.android") | ||
id("maven-publish") | ||
} | ||
|
||
android { | ||
namespace = "com.github.rumboalla.kryptostore" | ||
compileSdk = 34 | ||
|
||
defaultConfig { | ||
minSdk = 16 | ||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
buildTypes { | ||
release { | ||
isMinifyEnabled = true | ||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") | ||
} | ||
} | ||
|
||
compileOptions { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
} | ||
|
||
kotlinOptions { | ||
jvmTarget = "1.8" | ||
} | ||
|
||
testOptions { | ||
targetSdk = 34 | ||
} | ||
} | ||
|
||
dependencies { | ||
api("androidx.datastore:datastore-preferences:1.0.0") | ||
|
||
testImplementation("junit:junit:4.13.2") | ||
|
||
androidTestImplementation("androidx.test:runner:1.5.2") | ||
androidTestImplementation("androidx.test.ext:junit:1.1.5") | ||
} | ||
|
||
publishing { | ||
publications { | ||
create<MavenPublication>("maven") { | ||
groupId = "com.github.rumboalla.kryptostore" | ||
artifactId = "core" | ||
version = "0.1.0" | ||
} | ||
} | ||
} |
Empty file.
117 changes: 117 additions & 0 deletions
117
core/src/androidTest/kotlin/com/github/rumboalla/kryptostore/KryptoStoreInstrumentedTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package com.github.rumboalla.kryptostore | ||
|
||
import android.content.Context | ||
import androidx.datastore.core.DataStore | ||
import androidx.datastore.preferences.core.Preferences | ||
import androidx.datastore.preferences.core.edit | ||
import androidx.datastore.preferences.preferencesDataStore | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.platform.app.InstrumentationRegistry | ||
import com.github.rumboalla.kryptostore.annotation.DangerousApi | ||
import com.github.rumboalla.kryptostore.preference.booleanPref | ||
import com.github.rumboalla.kryptostore.preference.doublePref | ||
import com.github.rumboalla.kryptostore.preference.floatPref | ||
import com.github.rumboalla.kryptostore.preference.genPref | ||
import com.github.rumboalla.kryptostore.preference.intPref | ||
import com.github.rumboalla.kryptostore.preference.stringPref | ||
import com.github.rumboalla.kryptostore.preference.stringSetPref | ||
import com.github.rumboalla.kryptostore.transform.Transform | ||
import junit.framework.TestCase.assertEquals | ||
import kotlinx.coroutines.runBlocking | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
|
||
private val Context.store: DataStore<Preferences> by preferencesDataStore(name = "test") | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class KryptoStoreInstrumentedTest { | ||
|
||
private val context = InstrumentationRegistry.getInstrumentation().targetContext | ||
|
||
init { | ||
// Clears the datastore | ||
runBlocking { context.store.edit { it.clear() } } | ||
} | ||
|
||
@OptIn(DangerousApi::class) | ||
@Test | ||
fun testBoolean() = runBlocking { | ||
val pref = booleanPref(context.store, "testBoolean", false) | ||
assertEquals(pref.get(), false) | ||
pref.set(true) | ||
assertEquals(pref.get(), true) | ||
pref.set(false) | ||
assertEquals(pref.getBlocking(), false) | ||
} | ||
|
||
@OptIn(DangerousApi::class) | ||
@Test | ||
fun testInt() = runBlocking { | ||
val pref = intPref(context.store, "testInt", 0) | ||
assertEquals(pref.get(), 0) | ||
pref.set(1) | ||
assertEquals(pref.get(), 1) | ||
pref.set(2) | ||
assertEquals(pref.getBlocking(), 2) | ||
} | ||
|
||
@OptIn(DangerousApi::class) | ||
@Test | ||
fun testFloat() = runBlocking { | ||
val pref = floatPref(context.store, "testFloat", 0f) | ||
assertEquals(pref.get(), 0f) | ||
pref.set(1f) | ||
assertEquals(pref.get(), 1f) | ||
pref.set(2f) | ||
assertEquals(pref.getBlocking(), 2f) | ||
} | ||
|
||
@OptIn(DangerousApi::class) | ||
@Test | ||
fun testDouble() = runBlocking { | ||
val pref = doublePref(context.store, "testDouble", 0.0) | ||
assertEquals(pref.get(), 0.0) | ||
pref.set(1.0) | ||
assertEquals(pref.get(), 1.0) | ||
pref.set(2.0) | ||
assertEquals(pref.getBlocking(), 2.0) | ||
} | ||
|
||
@OptIn(DangerousApi::class) | ||
@Test | ||
fun testString() = runBlocking { | ||
val pref = stringPref(context.store, "testString", "42") | ||
assertEquals(pref.get(), "42") | ||
pref.set("Don't Panic") | ||
assertEquals(pref.get(), "Don't Panic") | ||
pref.set("Mostly Harmless") | ||
assertEquals(pref.getBlocking(), "Mostly Harmless") | ||
} | ||
|
||
@OptIn(DangerousApi::class) | ||
@Test | ||
fun testStringSet() = runBlocking { | ||
val pref = stringSetPref(context.store, "testStringSet", setOf("42", "Don't Panic", "Mostly Harmless")) | ||
assertEquals(pref.get(), setOf("42", "Don't Panic", "Mostly Harmless")) | ||
pref.set(setOf("Don't Panic", "Mostly Harmless", "42")) | ||
assertEquals(pref.get(), setOf("Don't Panic", "Mostly Harmless", "42")) | ||
pref.set(setOf("Mostly Harmless", "42", "Don't Panic")) | ||
assertEquals(pref.getBlocking(), setOf("Mostly Harmless", "42", "Don't Panic")) | ||
} | ||
|
||
@OptIn(DangerousApi::class) | ||
@Test | ||
fun testGenPref() = runBlocking { | ||
val transform = object : Transform<Float> { | ||
override fun transform(t: Float): String = t.toString() | ||
override fun transform(t: String): Float = t.toFloat() | ||
} | ||
val pref = genPref(context.store, "genPref", 0f, transform) | ||
assertEquals(pref.get(), 0f) | ||
pref.set(1f) | ||
assertEquals(pref.get(), 1f) | ||
pref.set(2f) | ||
assertEquals(pref.getBlocking(), 2f) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest/> |
6 changes: 6 additions & 0 deletions
6
core/src/main/kotlin/com/github/rumboalla/kryptostore/annotation/DangerousApi.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.github.rumboalla.kryptostore.annotation | ||
|
||
|
||
@RequiresOptIn("This is a dangerous call. Please make sure you understand how it works.") | ||
@Retention(AnnotationRetention.BINARY) | ||
annotation class DangerousApi |
26 changes: 26 additions & 0 deletions
26
core/src/main/kotlin/com/github/rumboalla/kryptostore/preference/GenericPreference.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.github.rumboalla.kryptostore.preference | ||
|
||
import androidx.datastore.core.DataStore | ||
import androidx.datastore.preferences.core.Preferences | ||
import androidx.datastore.preferences.core.edit | ||
import androidx.datastore.preferences.core.stringPreferencesKey | ||
import kotlinx.coroutines.flow.first | ||
import kotlinx.coroutines.flow.map | ||
import com.github.rumboalla.kryptostore.transform.Transform | ||
|
||
|
||
open class GenericPreference<T>( | ||
private val store: DataStore<Preferences>, | ||
name: String, | ||
private val defValue: T, | ||
private val transform: Transform<T> | ||
): Preference<T> { | ||
private val key = stringPreferencesKey(name) | ||
private val flow = store.data | ||
.map { it[key] ?: transform.transform(defValue) } | ||
.map { transform.transform(it) } | ||
|
||
override suspend fun get() = flow.first() | ||
override suspend fun set(v: T) { store.edit { it[key] = transform.transform(v) } } | ||
override fun flow() = flow | ||
} |
38 changes: 38 additions & 0 deletions
38
core/src/main/kotlin/com/github/rumboalla/kryptostore/preference/Preference.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.github.rumboalla.kryptostore.preference | ||
|
||
import com.github.rumboalla.kryptostore.annotation.DangerousApi | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.runBlocking | ||
|
||
|
||
interface Preference<T> { | ||
|
||
/** | ||
* Gets the value of a preference. | ||
* | ||
* @return {@T} Value of the preference. | ||
*/ | ||
suspend fun get(): T | ||
|
||
/** | ||
* Sets the value of a preference. | ||
* | ||
* @param v {@T} Value {@T} to set in the preference. | ||
*/ | ||
suspend fun set(v: T) | ||
|
||
/** | ||
* Returns a flow of the preference. | ||
* | ||
* @return {@Flow<T>} Flow of the preference. | ||
*/ | ||
fun flow(): Flow<T> | ||
|
||
/** | ||
* Gets the value of the preference. This call blocks until the preference is retrieved. | ||
* | ||
* @return {@T} Value of the preference. | ||
*/ | ||
@DangerousApi | ||
fun getBlocking() = runBlocking { get() } | ||
} |
33 changes: 33 additions & 0 deletions
33
core/src/main/kotlin/com/github/rumboalla/kryptostore/preference/PreferenceHelper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.github.rumboalla.kryptostore.preference | ||
|
||
import androidx.datastore.core.DataStore | ||
import androidx.datastore.preferences.core.Preferences | ||
import androidx.datastore.preferences.core.booleanPreferencesKey | ||
import androidx.datastore.preferences.core.doublePreferencesKey | ||
import androidx.datastore.preferences.core.floatPreferencesKey | ||
import androidx.datastore.preferences.core.intPreferencesKey | ||
import androidx.datastore.preferences.core.stringPreferencesKey | ||
import androidx.datastore.preferences.core.stringSetPreferencesKey | ||
import com.github.rumboalla.kryptostore.transform.Transform | ||
|
||
|
||
fun intPref(store: DataStore<Preferences>, name: String, defValue: Int) = | ||
PrimitivePreference(store, intPreferencesKey(name), defValue) | ||
|
||
fun stringPref(store: DataStore<Preferences>, name: String, defValue: String) = | ||
PrimitivePreference(store, stringPreferencesKey(name), defValue) | ||
|
||
fun booleanPref(store: DataStore<Preferences>, name: String, defValue: Boolean) = | ||
PrimitivePreference(store, booleanPreferencesKey(name), defValue) | ||
|
||
fun doublePref(store: DataStore<Preferences>, name: String, defValue: Double) = | ||
PrimitivePreference(store, doublePreferencesKey(name), defValue) | ||
|
||
fun floatPref(store: DataStore<Preferences>, name: String, defValue: Float) = | ||
PrimitivePreference(store, floatPreferencesKey(name), defValue) | ||
|
||
fun stringSetPref(store: DataStore<Preferences>, name: String, defValue: Set<String>) = | ||
PrimitivePreference(store, stringSetPreferencesKey(name), defValue) | ||
|
||
fun <T> genPref(store: DataStore<Preferences>, name: String, defValue: T, transform: Transform<T>) = | ||
GenericPreference(store, name, defValue, transform) |
20 changes: 20 additions & 0 deletions
20
core/src/main/kotlin/com/github/rumboalla/kryptostore/preference/PrimitivePreference.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.github.rumboalla.kryptostore.preference | ||
|
||
import androidx.datastore.core.DataStore | ||
import androidx.datastore.preferences.core.Preferences | ||
import androidx.datastore.preferences.core.edit | ||
import kotlinx.coroutines.flow.first | ||
import kotlinx.coroutines.flow.map | ||
|
||
|
||
open class PrimitivePreference<T>( | ||
private val store: DataStore<Preferences>, | ||
private val key: Preferences.Key<T>, | ||
private val defValue: T | ||
): Preference<T> { | ||
private val flow = store.data.map { it[key] ?: defValue } | ||
|
||
override suspend fun get() = flow.first() | ||
override suspend fun set(v: T) { store.edit { it[key] = v } } | ||
override fun flow() = flow | ||
} |
Oops, something went wrong.