Skip to content

Commit d8b58b4

Browse files
authored
feat(sampleapp): Adding sample app (#132)
Signed-off-by: Nicklas Lundin <[email protected]> Signed-off-by: Nicklas Lundin <[email protected]>
1 parent 9847a52 commit d8b58b4

32 files changed

+878
-2
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ This should only be called when your application is in the process of shutting d
211211
```kotlin
212212
OpenFeatureAPI.shutdown()
213213
```
214+
## Sample app
215+
216+
In the repo there is also a sample app currently under development.
217+
The sample app can be used to try out development of a [Provider](#develop-a-provider), a [Hook](#develop-a-hook)
218+
or to validate changes to the SDK itself.
219+
220+
The sample app should not be used as a reference implementation of how to use the OpenFeature SDK
221+
in an Android app.
214222

215223
## Extending
216224

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
plugins {
33
id("com.android.library").version("7.4.2").apply(false)
4+
id("com.android.application").version("7.4.2").apply(false)
45
id("org.jetbrains.kotlin.android").version("1.8.10").apply(false)
56
id("org.jlleitschuh.gradle.ktlint").version("11.6.1").apply(true)
67
id("io.github.gradle-nexus.publish-plugin").version("2.0.0").apply(true)

release-please-config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"README.md",
1111
"build.gradle.kts",
1212
"android/build.gradle.kts"
13-
]
13+
],
14+
"exclude-paths": ["sampleapp"]
1415
}
1516
},
1617
"changelog-sections": [

sampleapp/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

sampleapp/build.gradle.kts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
plugins {
2+
id("com.android.application")
3+
id("org.jetbrains.kotlin.android")
4+
}
5+
6+
android {
7+
namespace = "dev.openfeature.sdk.sampleapp"
8+
compileSdk = 33
9+
10+
defaultConfig {
11+
applicationId = "dev.openfeature.sdk.sampleapp"
12+
minSdk = 28
13+
targetSdk = 33
14+
versionCode = 1
15+
versionName = "1.0"
16+
17+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
18+
vectorDrawables {
19+
useSupportLibrary = true
20+
}
21+
}
22+
23+
buildTypes {
24+
release {
25+
isMinifyEnabled = false
26+
proguardFiles(
27+
getDefaultProguardFile("proguard-android-optimize.txt"),
28+
"proguard-rules.pro"
29+
)
30+
}
31+
}
32+
compileOptions {
33+
sourceCompatibility = JavaVersion.VERSION_11
34+
targetCompatibility = JavaVersion.VERSION_11
35+
}
36+
kotlinOptions {
37+
jvmTarget = "11"
38+
}
39+
buildFeatures {
40+
compose = true
41+
}
42+
composeOptions {
43+
kotlinCompilerExtensionVersion = "1.4.4"
44+
}
45+
packagingOptions {
46+
resources {
47+
excludes += "/META-INF/{AL2.0,LGPL2.1}"
48+
}
49+
}
50+
}
51+
52+
dependencies {
53+
implementation(project(":android"))
54+
implementation("androidx.core:core-ktx:1.7.0")
55+
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
56+
implementation("androidx.activity:activity-compose:1.3.0")
57+
implementation(platform("androidx.compose:compose-bom:2022.10.00"))
58+
implementation("androidx.compose.ui:ui")
59+
implementation("androidx.compose.ui:ui-graphics")
60+
implementation("androidx.compose.ui:ui-tooling-preview")
61+
implementation("androidx.compose.material3:material3")
62+
debugImplementation("androidx.compose.ui:ui-tooling")
63+
debugImplementation("androidx.compose.ui:ui-test-manifest")
64+
}

sampleapp/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<application
5+
android:allowBackup="true"
6+
android:icon="@mipmap/ic_launcher"
7+
android:label="@string/app_name"
8+
android:roundIcon="@mipmap/ic_launcher_round"
9+
android:supportsRtl="true"
10+
android:theme="@style/Theme.OpenFeature">
11+
<activity
12+
android:name=".MainActivity"
13+
android:exported="true"
14+
android:label="@string/app_name"
15+
android:theme="@style/Theme.OpenFeature">
16+
<intent-filter>
17+
<action android:name="android.intent.action.MAIN" />
18+
19+
<category android:name="android.intent.category.LAUNCHER" />
20+
</intent-filter>
21+
</activity>
22+
</application>
23+
24+
</manifest>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package dev.openfeature.sdk.sampleapp
2+
3+
import dev.openfeature.sdk.*
4+
import kotlinx.coroutines.delay
5+
6+
class ExampleProvider(override val hooks: List<Hook<*>> = listOf()) : FeatureProvider {
7+
8+
private var currentContext: EvaluationContext? = ImmutableContext()
9+
var delayTime = 1000L
10+
var returnDefaults = false
11+
val flags = mutableMapOf<String, Any>().apply {
12+
put("booleanFlag", true)
13+
put("stringFlag", "this is a string")
14+
put("intFlag", 1337)
15+
put("doubleFlag", 42.0)
16+
put(
17+
"objectFlag",
18+
Value.Structure(mapOf("key1" to Value.String("value"), "key2" to Value.Integer(10)))
19+
)
20+
}
21+
22+
override val metadata: ProviderMetadata
23+
get() = object : ProviderMetadata {
24+
override val name: String = "ExampleProvider"
25+
}
26+
27+
override suspend fun initialize(initialContext: EvaluationContext?) {
28+
currentContext = initialContext
29+
// Simulate a delay in the provider initialization
30+
delay(delayTime)
31+
}
32+
33+
override fun shutdown() {
34+
35+
}
36+
37+
override suspend fun onContextSet(
38+
oldContext: EvaluationContext?,
39+
newContext: EvaluationContext
40+
) {
41+
currentContext = newContext
42+
delay(delayTime)
43+
}
44+
45+
override fun getBooleanEvaluation(
46+
key: String,
47+
defaultValue: Boolean,
48+
context: EvaluationContext?
49+
): ProviderEvaluation<Boolean> = generateProviderEvaluation<Boolean>(defaultValue, key)
50+
51+
override fun getStringEvaluation(
52+
key: String,
53+
defaultValue: String,
54+
context: EvaluationContext?
55+
): ProviderEvaluation<String> = generateProviderEvaluation<String>(defaultValue, key)
56+
57+
override fun getIntegerEvaluation(
58+
key: String,
59+
defaultValue: Int,
60+
context: EvaluationContext?
61+
): ProviderEvaluation<Int> = generateProviderEvaluation<Int>(defaultValue, key)
62+
63+
override fun getDoubleEvaluation(
64+
key: String,
65+
defaultValue: Double,
66+
context: EvaluationContext?
67+
): ProviderEvaluation<Double> = generateProviderEvaluation<Double>(defaultValue, key)
68+
69+
override fun getObjectEvaluation(
70+
key: String,
71+
defaultValue: Value,
72+
context: EvaluationContext?
73+
): ProviderEvaluation<Value> = generateProviderEvaluation<Value>(defaultValue, key)
74+
75+
private inline fun <reified T> generateProviderEvaluation(
76+
defaultValue: T,
77+
key: String
78+
): ProviderEvaluation<T> {
79+
if (returnDefaults) {
80+
return ProviderEvaluation(defaultValue, null, reason = "returnDefaults")
81+
}
82+
return with(flags) {
83+
if (containsKey(key) && get(key) is T) {
84+
ProviderEvaluation(get(key) as T, "variant1", reason = "match")
85+
} else if (containsKey(key)) {
86+
ProviderEvaluation(defaultValue, null, reason = "invalid type")
87+
} else {
88+
ProviderEvaluation(defaultValue, null, reason = "notfound")
89+
}
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)