11package io.getunleash.android
22
33import android.content.Context
4- import android.util.Log
54import androidx.lifecycle.Lifecycle
65import androidx.lifecycle.LifecycleOwner
76import androidx.lifecycle.ProcessLifecycleOwner
@@ -31,6 +30,7 @@ import io.getunleash.android.metrics.NoOpMetrics
3130import io.getunleash.android.polling.UnleashFetcher
3231import io.getunleash.android.tasks.DataJob
3332import io.getunleash.android.tasks.LifecycleAwareTaskManager
33+ import io.getunleash.android.util.UnleashLogger
3434import kotlinx.collections.immutable.toImmutableList
3535import kotlinx.coroutines.CoroutineExceptionHandler
3636import kotlinx.coroutines.CoroutineScope
@@ -56,7 +56,7 @@ import java.util.concurrent.TimeoutException
5656import java.util.concurrent.atomic.AtomicBoolean
5757
5858val unleashExceptionHandler = CoroutineExceptionHandler { _, exception ->
59- Log .e(" UnleashHandler" , " Caught unhandled exception: ${exception.message} " , exception)
59+ UnleashLogger .e(" UnleashHandler" , " Caught unhandled exception: ${exception.message} " , exception)
6060}
6161
6262private val job = SupervisorJob ()
@@ -145,13 +145,13 @@ class DefaultUnleash(
145145 }
146146 }
147147
148- fun start (
149- eventListeners : List <UnleashListener > = emptyList() ,
150- bootstrapFile : File ? = null ,
151- bootstrap : List <Toggle > = emptyList()
148+ override fun start (
149+ eventListeners : List <UnleashListener >,
150+ bootstrapFile : File ? ,
151+ bootstrap : List <Toggle >
152152 ) {
153153 if (! started.compareAndSet(false , true )) {
154- Log .w(TAG , " Unleash already started, ignoring start call" )
154+ UnleashLogger .w(TAG , " Unleash already started, ignoring start call" )
155155 return
156156 }
157157 initialListeners.forEach { addUnleashEventListener(it) }
@@ -170,14 +170,14 @@ class DefaultUnleash(
170170 cache.subscribeTo(fetcher.getFeaturesReceivedFlow())
171171 lifecycle.addObserver(taskManager)
172172 if (bootstrapFile != null && bootstrapFile.exists()) {
173- Log .i(TAG , " Using provided bootstrap file" )
173+ UnleashLogger .i(TAG , " Using provided bootstrap file" )
174174 Parser .proxyResponseAdapter.fromJson(bootstrapFile.readText())?.let { state ->
175175 val toggles = state.toggles.groupBy { it.name }
176176 .mapValues { (_, v) -> v.first() }
177177 cache.write(UnleashState (unleashContextState.value, toggles))
178178 }
179179 } else if (bootstrap.isNotEmpty()) {
180- Log .i(TAG , " Using provided bootstrap toggles" )
180+ UnleashLogger .i(TAG , " Using provided bootstrap toggles" )
181181 cache.write(UnleashState (unleashContextState.value, bootstrap.associateBy { it.name }))
182182 }
183183 }
@@ -213,20 +213,35 @@ class DefaultUnleash(
213213 // subscribe to feature updates from upstream
214214 localBackup.subscribeTo(fetcher.getFeaturesReceivedFlow())
215215 unleashContextState.asStateFlow().takeWhile { ! ready.get() }.collect { ctx ->
216- Log .d(TAG , " Loading state from backup for $ctx " )
216+ UnleashLogger .d(TAG , " Loading state from backup for $ctx " )
217217 localBackup.loadFromDisc(unleashContextState.value)?.let { state ->
218218 if (! ready.get()) {
219- Log .i(TAG , " Loaded state from backup for $ctx " )
219+ UnleashLogger .i(TAG , " Loaded state from backup for $ctx " )
220220 cache.write(state)
221221 } else {
222- Log .d(TAG , " Ignoring backup, Unleash is already ready" )
222+ UnleashLogger .d(TAG , " Ignoring backup, Unleash is already ready" )
223223 }
224224 }
225225 }
226226 }
227227 }
228228 }
229229
230+ override fun isEnabled (toggleName : String ): Boolean {
231+ val toggle = cache.get(toggleName)
232+ val enabled = toggle?.enabled ? : false
233+ val impressionData = unleashConfig.forceImpressionData || toggle?.impressionData ? : false
234+ if (impressionData) {
235+ emit(ImpressionEvent (toggleName, enabled, unleashContextState.value))
236+ }
237+ metrics.count(toggleName, enabled)
238+ return enabled
239+ }
240+
241+ @Deprecated(
242+ " Use isEnabled(toggleName: String) instead. See https://github.com/Unleash/unleash-android-sdk/issues/141" ,
243+ replaceWith = ReplaceWith (" isEnabled(toggleName)" )
244+ )
230245 override fun isEnabled (toggleName : String , defaultValue : Boolean ): Boolean {
231246 val toggle = cache.get(toggleName)
232247 val enabled = toggle?.enabled ? : defaultValue
@@ -238,6 +253,22 @@ class DefaultUnleash(
238253 return enabled
239254 }
240255
256+ override fun getVariant (toggleName : String ): Variant {
257+ val toggle = cache.get(toggleName)
258+ val enabled = isEnabled(toggleName)
259+ val variant = if (enabled) (toggle?.variant ? : disabledVariant) else disabledVariant
260+ val impressionData = toggle?.impressionData ? : unleashConfig.forceImpressionData
261+ if (impressionData) {
262+ emit(ImpressionEvent (toggleName, enabled, unleashContextState.value, variant.name))
263+ }
264+ metrics.countVariant(toggleName, variant)
265+ return variant
266+ }
267+
268+ @Deprecated(
269+ " Use getVariant(toggleName: String) instead. See https://github.com/Unleash/unleash-android-sdk/issues/141" ,
270+ replaceWith = ReplaceWith (" getVariant(toggleName)" )
271+ )
241272 override fun getVariant (toggleName : String , defaultValue : Variant ): Variant {
242273 val toggle = cache.get(toggleName)
243274 val enabled = isEnabled(toggleName)
@@ -336,7 +367,7 @@ class DefaultUnleash(
336367 if (listener is UnleashReadyListener ) {
337368 val job = coroutineScope.launch {
338369 readyOnFeaturesReceived()
339- Log .d(TAG , " Notifying UnleashReadyListener" )
370+ UnleashLogger .d(TAG , " Notifying UnleashReadyListener" )
340371 listener.onReady()
341372 }
342373 registerListenerJob(listener, job)
@@ -391,9 +422,9 @@ class DefaultUnleash(
391422 val first = cache.getUpdatesFlow().first { it ->
392423 it.toggles.isNotEmpty()
393424 }
394- Log .d(TAG , " Received first cache update: $first " )
425+ UnleashLogger .d(TAG , " Received first cache update: $first " )
395426 if (ready.compareAndSet(false , true )) {
396- Log .d(TAG , " Unleash state changed to ready" )
427+ UnleashLogger .d(TAG , " Unleash state changed to ready" )
397428 }
398429 }
399430
@@ -408,9 +439,9 @@ class DefaultUnleash(
408439
409440private fun getLifecycle (androidContext : Context ) =
410441 if (androidContext is LifecycleOwner ) {
411- Log .d(" Unleash" , " Using lifecycle from Android context" )
442+ UnleashLogger .d(" Unleash" , " Using lifecycle from Android context" )
412443 androidContext.lifecycle
413444 } else {
414- Log .d(" Unleash" , " Using lifecycle from ProcessLifecycleOwner" )
445+ UnleashLogger .d(" Unleash" , " Using lifecycle from ProcessLifecycleOwner" )
415446 ProcessLifecycleOwner .get().lifecycle
416447 }
0 commit comments