Skip to content

Commit

Permalink
Start building info view in sample application
Browse files Browse the repository at this point in the history
  • Loading branch information
erikeelde committed Sep 23, 2024
1 parent 3192127 commit b4be68a
Show file tree
Hide file tree
Showing 26 changed files with 305 additions and 150 deletions.
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx-
androidx-test-runner = "androidx.test:runner:1.6.2"
app-cash-licensee-licensee-gradle-plugin = "app.cash.licensee:licensee-gradle-plugin:1.11.0"
app-cash-turbine = "app.cash.turbine:turbine:1.1.0"
co-touchlab-kermit = "co.touchlab:kermit:2.0.4"
com-android-tools-build-gradle = "com.android.tools.build:gradle:8.6.1"
com-google-dagger = { module = "com.google.dagger:dagger", version.ref = "com-google-dagger" }
com-google-dagger-dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "com-google-dagger" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,32 @@ interface ProviderConfigurationDao {
)
fun updateConfiguration(callingApplication: Long, id: Long, key: String, type: String): Int

@Query(
"SELECT * FROM configuration WHERE applicationId = :callingApplication"
)
fun getConfigurationCursor(callingApplication: Long): Cursor

@Query("SELECT * FROM configuration WHERE id = :configurationId and applicationId = :callingApplication")
fun getConfigurationCursor(callingApplication: Long, configurationId: Long): Cursor

@Query(
"SELECT * FROM configuration WHERE configurationKey = :configurationKey and applicationId = :callingApplication"
)
fun getConfigurationCursor(callingApplication: Long, configurationKey: String): Cursor

@Query(
"""SELECT configurationValue.* FROM configuration
INNER JOIN configurationValue ON configuration.id = configurationValue.configurationId
WHERE configuration.applicationId = :callingApplication AND configurationId = :configurationId
"""
)
fun getConfigurationValueCursor(callingApplication: Long, configurationId: Long): Cursor

@Query(
"""SELECT configurationValue.* FROM configuration
INNER JOIN configurationValue ON configuration.id = configurationValue.configurationId
WHERE configuration.applicationId = :callingApplication AND configurationKey = :configurationKey
"""
)
fun getConfigurationValueCursor(callingApplication: Long, configurationKey: String): Cursor
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,36 @@ class TogglesProvider : ContentProvider() {
}
}

UriMatch.CONFIGURATIONS -> {
cursor = configurationDao.getConfigurationCursor(callingApplication.id)
}

UriMatch.CONFIGURATION_KEY -> {
cursor = configurationDao.getConfigurationCursor(callingApplication.id, uri.lastPathSegment!!)
cursor = configurationDao.getConfigurationCursor(
callingApplication.id,
uri.lastPathSegment!!
)
}

UriMatch.CONFIGURATION_ID -> {
cursor = configurationDao.getConfigurationCursor(callingApplication.id, uri.lastPathSegment!!.toLong())
cursor = configurationDao.getConfigurationCursor(
callingApplication.id,
uri.lastPathSegment!!.toLong()
)
}

UriMatch.CONFIGURATION_VALUE_KEY -> {
cursor = configurationDao.getConfigurationValueCursor(
callingApplication.id,
uri.pathSegments.get(uri.pathSegments.size - 2)
)
}

UriMatch.CONFIGURATION_VALUE_ID -> {
cursor = configurationDao.getConfigurationValueCursor(
callingApplication.id,
uri.pathSegments.get(uri.pathSegments.size - 2).toLong()
)
}

else -> {
Expand Down Expand Up @@ -346,6 +370,7 @@ class TogglesProvider : ContentProvider() {
}
return deletedRows
}

UriMatch.CONFIGURATION_KEY -> {
val deletedRows =
configurationDao.deleteConfiguration(
Expand Down Expand Up @@ -393,6 +418,8 @@ class TogglesProvider : ContentProvider() {
UriMatch.PREDEFINED_CONFIGURATION_VALUES ->
"vnd.android.cursor.dir/vnd.${context!!.packageName}.predefinedConfigurationValue"

UriMatch.CONFIGURATION_VALUE_ID -> "vnd.android.cursor.dir/vnd.${context!!.packageName}.configurationValue"
UriMatch.CONFIGURATION_VALUE_KEY -> "vnd.android.cursor.dir/vnd.${context!!.packageName}.configurationValue"
UriMatch.UNKNOWN -> TODO()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ enum class UriMatch {
CONFIGURATIONS,
CONFIGURATION_ID,
CONFIGURATION_KEY,
CONFIGURATION_VALUE_ID,
CONFIGURATION_VALUE_KEY,
PREDEFINED_CONFIGURATION_VALUES,
UNKNOWN,
}
Expand Down Expand Up @@ -57,6 +59,16 @@ class TogglesUriMatcher(providerAuthority: String) {
"configuration/*",
UriMatch.CONFIGURATION_KEY.ordinal
)
uriMatcher.addURI(
providerAuthority,
"configuration/#/values",
UriMatch.CONFIGURATION_VALUE_ID.ordinal
)
uriMatcher.addURI(
providerAuthority,
"configuration/*/values",
UriMatch.CONFIGURATION_VALUE_KEY.ordinal
)
uriMatcher.addURI(
providerAuthority,
"predefinedConfigurationValue",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import dagger.hilt.android.testing.HiltTestApplication
import dagger.hilt.android.testing.UninstallModules
import dagger.hilt.components.SingletonComponent
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
Expand Down Expand Up @@ -110,15 +111,24 @@ class TogglesProviderMatcherConfigurationTest {
)
}

@Test(expected = UnsupportedOperationException::class)
val togglesConfiguration = TogglesConfiguration {
type = Toggle.TYPE.BOOLEAN
key = "myConfigurationkey"
}

@Test
fun testQuery() {
togglesProvider.query(
togglesProvider.insert(
TogglesProviderContract.configurationUri(),
null,
null,
null,
null
togglesConfiguration.toContentValues(),
)

val cursor = togglesProvider.query(TogglesProviderContract.configurationUri(), null, null, null, null)
assertTrue(cursor.moveToFirst())
TogglesConfiguration.fromCursor(cursor).also { cursorConfiguration ->
assertEquals(togglesConfiguration.key, cursorConfiguration.key)
assertEquals(togglesConfiguration.type, cursorConfiguration.type)
}
}

@Test(expected = UnsupportedOperationException::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ public class TogglesConfigurationValue private constructor(
@JvmStatic
public fun fromCursor(cursor: Cursor): TogglesConfigurationValue {
return TogglesConfigurationValue(
id = cursor.getLongOrThrow(ColumnNames.Toggle.COL_ID),
configurationId = cursor.getLongOrThrow(ColumnNames.Toggle.COL_TYPE),
value = cursor.getStringOrNull(ColumnNames.Toggle.COL_VALUE),
scope = cursor.getLongOrThrow(ColumnNames.Toggle.COL_KEY),
id = cursor.getLongOrThrow(ColumnNames.ConfigurationValue.COL_ID),
configurationId = cursor.getLongOrThrow(ColumnNames.ConfigurationValue.COL_CONFIG_ID),
value = cursor.getStringOrNull(ColumnNames.ConfigurationValue.COL_VALUE),
scope = cursor.getLongOrThrow(ColumnNames.ConfigurationValue.COL_SCOPE),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ public object TogglesProviderContract {
private const val TOGGLES_API_VERSION = 1

private val configurationUri = Uri.parse("content://$TOGGLES_AUTHORITY/configuration")

private val currentConfigurationUri =
Uri.parse("content://$TOGGLES_AUTHORITY/currentConfiguration")
private val configurationValueUri =
private val currentConfigurationValueUri =
Uri.parse("content://$TOGGLES_AUTHORITY/predefinedConfigurationValue")

@JvmStatic
Expand Down Expand Up @@ -41,7 +42,7 @@ public object TogglesProviderContract {

@JvmStatic
public fun toggleValueUri(): Uri {
return configurationValueUri
return currentConfigurationValueUri
.buildUpon()
.appendQueryParameter(TOGGLES_API_VERSION_QUERY_PARAM, TOGGLES_API_VERSION.toString())
.build()
Expand Down Expand Up @@ -72,4 +73,24 @@ public object TogglesProviderContract {
.appendQueryParameter(TOGGLES_API_VERSION_QUERY_PARAM, TOGGLES_API_VERSION.toString())
.build()
}

@JvmStatic
public fun configurationValueUri(key: String): Uri {
return configurationUri
.buildUpon()
.appendPath(key)
.appendPath("values")
.appendQueryParameter(TOGGLES_API_VERSION_QUERY_PARAM, TOGGLES_API_VERSION.toString())
.build()
}

@JvmStatic
public fun configurationValueUri(id: Long): Uri {
return configurationUri
.buildUpon()
.appendPath(id.toString())
.appendPath("values")
.appendQueryParameter(TOGGLES_API_VERSION_QUERY_PARAM, TOGGLES_API_VERSION.toString())
.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ public interface Toggles {
type: Class<T>,
defaultValue: T
): Flow<T>
public suspend fun hasToggle(key: String): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ public class TogglesImpl(@Suppress("UNUSED_PARAMETER") context: Context) : Toggl
type: Class<T>,
defaultValue: T
): Flow<T> = flowOf(defaultValue)

override suspend fun hasToggle(key: String): Boolean = false
}
2 changes: 2 additions & 0 deletions toggles-flow/src/main/java/se/eelde/toggles/flow/Toggles.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public interface Toggles {
type: Class<T>,
defaultValue: T
): Flow<T>

public suspend fun hasToggle(key: String): Boolean
}
13 changes: 13 additions & 0 deletions toggles-flow/src/main/java/se/eelde/toggles/flow/TogglesImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import se.eelde.toggles.core.Toggle
import se.eelde.toggles.core.Toggle.Companion.fromCursor
import se.eelde.toggles.core.Toggle.ToggleType
import se.eelde.toggles.core.ToggleValue
import se.eelde.toggles.core.TogglesProviderContract.configurationUri
import se.eelde.toggles.core.TogglesProviderContract.toggleUri
import se.eelde.toggles.core.TogglesProviderContract.toggleValueUri

Expand Down Expand Up @@ -115,6 +116,18 @@ public class TogglesImpl(context: Context) : Toggles {
}
}

override suspend fun hasToggle(key: String): Boolean {
return contentResolver.query(
configurationUri(key),
null,
null,
null,
null
).use { cursor ->
cursor != null && cursor.count > 0
}
}

private fun providerToggleFlow(
context: Context,
@ToggleType type: String,
Expand Down
11 changes: 7 additions & 4 deletions toggles-sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins {
id("app.cash.licensee")
alias(libs.plugins.se.premex.gross)
alias(libs.plugins.com.google.devtools.ksp)
alias(libs.plugins.org.jetbrains.kotlin.plugin.serialization)
}

val versionFile = File("versions.properties")
Expand All @@ -32,8 +33,9 @@ licensee {
}

android {
namespace = "se.eelde.toggles.example"

defaultConfig {
applicationId = "se.eelde.toggles.example"
versionName = versions.getProperty("V_VERSION", "0.0.1")
versionCode = versions.getProperty("V_VERSION_CODE", "1").toInt()

Expand All @@ -50,7 +52,6 @@ android {
applicationIdSuffix = ".debug"
}
}
namespace = "com.example.toggles"
}

kotlin {
Expand All @@ -73,16 +74,18 @@ dependencies {
implementation(libs.androidx.lifecycle.lifecycle.viewmodel.compose)
implementation(libs.androidx.hilt.hilt.navigation.compose)
implementation(libs.androidx.navigation.navigation.compose)

implementation(libs.co.touchlab.kermit)
implementation(libs.org.jetbrains.kotlinx.kotlinx.serialization.json)
implementation(libs.org.jetbrains.kotlinx.kotlinx.collections.immutable)
implementation(projects.modules.composeTheme)
implementation(projects.modules.oss)

implementation(libs.com.google.dagger.hilt.android)
ksp(libs.com.google.dagger.hilt.android.compiler)
kspTest(libs.com.google.dagger.hilt.android.compiler)

implementation(libs.se.eelde.toggles.toggles.core)
implementation(libs.se.eelde.toggles.toggles.flow)
implementation(libs.se.eelde.toggles.toggles.prefs)

implementation(platform(libs.org.jetbrains.kotlinx.kotlinx.coroutines.bom))
implementation(libs.org.jetbrains.kotlinx.kotlinx.coroutines.android)
Expand Down
4 changes: 2 additions & 2 deletions toggles-sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<application
android:name="com.example.toggles.SampleApplication"
android:name="se.eelde.toggles.example.SampleApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -17,7 +17,7 @@
tools:ignore="GoogleAppIndexingWarning"
tools:targetApi="31">
<activity
android:name="com.example.toggles.MainActivity"
android:name="se.eelde.toggles.example.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down

This file was deleted.

Loading

0 comments on commit b4be68a

Please sign in to comment.