Add feature flags that contains new image loader flag.
This allows to release new versions of the app with unfinished/ not fully implemented features. Signed-off-by: Yahor Berdnikau <egorr.berd@gmail.com>
This commit is contained in:
parent
02467cb05b
commit
a63c47112c
|
@ -44,6 +44,7 @@ import org.moire.ultrasonic.domain.MusicDirectory;
|
|||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
||||
import org.moire.ultrasonic.domain.PlayerState;
|
||||
import org.moire.ultrasonic.domain.Share;
|
||||
import org.moire.ultrasonic.featureflags.Feature;
|
||||
import org.moire.ultrasonic.service.*;
|
||||
import org.moire.ultrasonic.subsonic.SubsonicImageLoaderProxy;
|
||||
import org.moire.ultrasonic.util.*;
|
||||
|
@ -790,10 +791,14 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen
|
|||
}
|
||||
}
|
||||
|
||||
public synchronized void clearImageLoader()
|
||||
{
|
||||
if (IMAGE_LOADER != null && IMAGE_LOADER.isRunning()) IMAGE_LOADER.clear();
|
||||
}
|
||||
public synchronized void clearImageLoader() {
|
||||
if (IMAGE_LOADER != null &&
|
||||
IMAGE_LOADER.isRunning()) {
|
||||
IMAGE_LOADER.clear();
|
||||
}
|
||||
|
||||
IMAGE_LOADER = null;
|
||||
}
|
||||
|
||||
public synchronized ImageLoader getImageLoader() {
|
||||
if (IMAGE_LOADER == null ||
|
||||
|
@ -802,10 +807,18 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen
|
|||
this,
|
||||
Util.getImageLoaderConcurrency(this)
|
||||
);
|
||||
IMAGE_LOADER = new SubsonicImageLoaderProxy(
|
||||
legacyImageLoader,
|
||||
((UApp) getApplication()).getSubsonicImageLoader()
|
||||
);
|
||||
|
||||
boolean isNewImageLoaderEnabled = ((UApp) getApplication()).getFeaturesStorage()
|
||||
.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER);
|
||||
if (isNewImageLoaderEnabled) {
|
||||
IMAGE_LOADER = new SubsonicImageLoaderProxy(
|
||||
legacyImageLoader,
|
||||
((UApp) getApplication()).getSubsonicImageLoader()
|
||||
);
|
||||
} else {
|
||||
IMAGE_LOADER = legacyImageLoader;
|
||||
}
|
||||
|
||||
IMAGE_LOADER.startImageLoader();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,29 +4,21 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.*;
|
||||
import android.provider.SearchRecentSuggestions;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.activity.ServerSettingsActivity;
|
||||
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
||||
import org.moire.ultrasonic.app.UApp;
|
||||
import org.moire.ultrasonic.featureflags.Feature;
|
||||
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
||||
import org.moire.ultrasonic.provider.SearchSuggestionProvider;
|
||||
import org.moire.ultrasonic.service.DownloadService;
|
||||
import org.moire.ultrasonic.service.DownloadServiceImpl;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.FileUtil;
|
||||
import org.moire.ultrasonic.util.ImageLoader;
|
||||
import org.moire.ultrasonic.util.TimeSpanPreference;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.util.*;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
@ -115,6 +107,7 @@ public class SettingsFragment extends PreferenceFragment
|
|||
sharingDefaultGreeting.setText(Util.getShareGreeting(getActivity()));
|
||||
setupClearSearchPreference();
|
||||
setupGaplessControlSettingsV14();
|
||||
setupFeatureFlagsPreferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -178,6 +171,24 @@ public class SettingsFragment extends PreferenceFragment
|
|||
}
|
||||
}
|
||||
|
||||
private void setupFeatureFlagsPreferences() {
|
||||
CheckBoxPreference ffImageLoader = (CheckBoxPreference) findPreference(
|
||||
Constants.PREFERENCES_KEY_FF_IMAGE_LOADER);
|
||||
|
||||
final FeatureStorage featureStorage = ((UApp) getActivity().getApplication()).getFeaturesStorage();
|
||||
if (ffImageLoader != null) {
|
||||
ffImageLoader.setChecked(featureStorage.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER));
|
||||
ffImageLoader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
featureStorage.changeFeatureFlag(Feature.NEW_IMAGE_DOWNLOADER, (Boolean) o);
|
||||
((SubsonicTabActivity) getActivity()).clearImageLoader();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setupGaplessControlSettingsV14() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
|
||||
PreferenceCategory playbackControlSettings =
|
||||
|
|
|
@ -130,6 +130,7 @@ public final class Constants
|
|||
public static final String PREFERENCES_KEY_SHOW_ALL_SONGS_BY_ARTIST = "showAllSongsByArtist";
|
||||
public static final String PREFERENCES_KEY_SCAN_MEDIA = "scanMedia";
|
||||
public static final String PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY = "imageLoaderConcurrency";
|
||||
public static final String PREFERENCES_KEY_FF_IMAGE_LOADER = "ff_new_image_loader";
|
||||
|
||||
// Number of free trial days for non-licensed servers.
|
||||
public static final int FREE_TRIAL_DAYS = 30;
|
||||
|
|
|
@ -5,7 +5,9 @@ import org.koin.android.ext.android.get
|
|||
import org.koin.android.ext.android.startKoin
|
||||
import org.moire.ultrasonic.di.baseNetworkModule
|
||||
import org.moire.ultrasonic.di.directoriesModule
|
||||
import org.moire.ultrasonic.di.featureFlagsModule
|
||||
import org.moire.ultrasonic.di.musicServiceModule
|
||||
import org.moire.ultrasonic.featureflags.FeatureStorage
|
||||
import org.moire.ultrasonic.subsonic.loader.image.SubsonicImageLoader
|
||||
import org.moire.ultrasonic.util.Util
|
||||
|
||||
|
@ -17,6 +19,7 @@ class UApp : Application() {
|
|||
startKoin(this, listOf(
|
||||
directoriesModule,
|
||||
baseNetworkModule,
|
||||
featureFlagsModule(this),
|
||||
musicServiceModule(sharedPreferences, this)
|
||||
))
|
||||
}
|
||||
|
@ -27,4 +30,11 @@ class UApp : Application() {
|
|||
fun getSubsonicImageLoader(): SubsonicImageLoader {
|
||||
return get()
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary method to get features storage.
|
||||
*/
|
||||
fun getFeaturesStorage(): FeatureStorage {
|
||||
return get()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package org.moire.ultrasonic.di
|
||||
|
||||
import android.content.Context
|
||||
import org.koin.dsl.module.applicationContext
|
||||
import org.moire.ultrasonic.featureflags.FeatureStorage
|
||||
|
||||
fun featureFlagsModule(
|
||||
context: Context
|
||||
) = applicationContext {
|
||||
factory { FeatureStorage(context) }
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.moire.ultrasonic.featureflags
|
||||
|
||||
/**
|
||||
* Contains a list of new features/implementations that are not yet finished,
|
||||
* but possible to try it out.
|
||||
*/
|
||||
enum class Feature(
|
||||
val defaultValue: Boolean
|
||||
) {
|
||||
/**
|
||||
* Enables new image downloader implementation.
|
||||
*/
|
||||
NEW_IMAGE_DOWNLOADER(false)
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.moire.ultrasonic.featureflags
|
||||
|
||||
import android.content.Context
|
||||
|
||||
private const val SP_NAME = "feature_flags"
|
||||
|
||||
/**
|
||||
* Provides storage for current feature flag state.
|
||||
*/
|
||||
class FeatureStorage(
|
||||
context: Context
|
||||
) {
|
||||
private val sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE)
|
||||
|
||||
/**
|
||||
* Get [feature] current enabled state.
|
||||
*/
|
||||
fun isFeatureEnabled(feature: Feature): Boolean {
|
||||
return sp.getBoolean(feature.name, feature.defaultValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update [feature] enabled state to [isEnabled].
|
||||
*/
|
||||
fun changeFeatureFlag(
|
||||
feature: Feature,
|
||||
isEnabled: Boolean
|
||||
) {
|
||||
sp.edit().putBoolean(feature.name, isEnabled).apply()
|
||||
}
|
||||
}
|
|
@ -436,5 +436,10 @@
|
|||
<string name="api.subsonic.trial_period_is_over">El período de prueba ha terminado.</string>
|
||||
<string name="api.subsonic.upgrade_client">Versiones incompatibles. Por favor actualiza la aplicación de Android UltraSonic.</string>
|
||||
<string name="api.subsonic.upgrade_server">Versiones incompatibles. Por favor actualiza el servidor de Subsonic.</string>
|
||||
<string name="feature_flags_category_title">Banderas de características</string>
|
||||
<string name="feature_flags_image_loader_description">Permite la implementación de un nuevo cargador de imágenes.
|
||||
Actualmente no guarda la imagen en el almacenamiento del dispositivo y sólo utiliza caché en la memoria.
|
||||
</string>
|
||||
<string name="feature_flags_image_loader_title">Habilitar nuevo cargador de imágenes</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -436,5 +436,11 @@
|
|||
<string name="api.subsonic.trial_period_is_over">La période d\'essai est terminée.</string>
|
||||
<string name="api.subsonic.upgrade_client">Versions incompatible. Veuillez mette à jour l\'application Android UltraSonic.</string>
|
||||
<string name="api.subsonic.upgrade_server">Versions incompatible. Veuillez mette à jour le serveur Subsonic.</string>
|
||||
<string name="feature_flags_category_title">Drapeaux des fonctionnalités</string>
|
||||
<string name="feature_flags_image_loader_description">Permet l\'implémentation d\'un nouveau chargeur d\'images.
|
||||
Actuellement, il n\'enregistre pas l\'image dans le stockage de l\'appareil et n\'utilise que le cache en
|
||||
mémoire.
|
||||
</string>
|
||||
<string name="feature_flags_image_loader_title">Activer le nouveau chargeur d\'images</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -436,5 +436,10 @@
|
|||
<string name="api.subsonic.trial_period_is_over">A próbaidő vége.</string>
|
||||
<string name="api.subsonic.upgrade_client">Nem kompatibilis verzió. Kérjük, frissítse az UltraSonic Android alkalmazást!</string>
|
||||
<string name="api.subsonic.upgrade_server">Nem kompatibilis verzió. Kérjük, frissítse a Subsonic kiszolgálót!</string>
|
||||
<string name="feature_flags_image_loader_description">Engedélyezi az új képbetöltő megvalósítását. Jelenleg nem
|
||||
tárolja a képet az eszköz tárolójában, és csak a memóriában tárolja a gyorsítótárat.
|
||||
</string>
|
||||
<string name="feature_flags_category_title">Jellemzők Zászlók</string>
|
||||
<string name="feature_flags_image_loader_title">Engedélyezzen új képbetöltőt</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -436,5 +436,10 @@
|
|||
<string name="api.subsonic.trial_period_is_over">O período de avaliação acabou.</string>
|
||||
<string name="api.subsonic.upgrade_client">Versões incompativeis. Atualize o aplicativo UltraSonic para Android.</string>
|
||||
<string name="api.subsonic.upgrade_server">Versões incompativeis. Atualize o servidor UltraSonic.</string>
|
||||
<string name="feature_flags_image_loader_description">Permite nova implementação do carregador de imagens.
|
||||
Atualmente, ele não salva a imagem no armazenamento do dispositivo e usa apenas o cache na memória.
|
||||
</string>
|
||||
<string name="feature_flags_category_title">Bandeiras de recursos</string>
|
||||
<string name="feature_flags_image_loader_title">Ativar novo carregador de imagens</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -436,5 +436,10 @@
|
|||
<string name="api.subsonic.trial_period_is_over">O período de avaliação acabou.</string>
|
||||
<string name="api.subsonic.upgrade_client">Versões incompativeis. Atualize o aplicativo UltraSonic para Android.</string>
|
||||
<string name="api.subsonic.upgrade_server">Versões incompativeis. Atualize o servidor UltraSonic.</string>
|
||||
<string name="feature_flags_image_loader_description">Permite nova implementação do carregador de imagens.
|
||||
Atualmente, ele não salva a imagem no armazenamento do dispositivo e usa apenas o cache na memória.
|
||||
</string>
|
||||
<string name="feature_flags_category_title">Bandeiras de recursos</string>
|
||||
<string name="feature_flags_image_loader_title">Ativar novo carregador de imagens</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -441,4 +441,10 @@
|
|||
<string name="api.subsonic.upgrade_client">Incompatible versions. Please upgrade UltraSonic Android app.</string>
|
||||
<string name="api.subsonic.upgrade_server">Incompatible versions. Please upgrade Subsonic server.</string>
|
||||
|
||||
<string name="feature_flags_image_loader_title">Enable new image loader</string>
|
||||
<string name="feature_flags_image_loader_description">Enables new image loader implementation.
|
||||
Currently it doesn\'t save image in device storage and uses only cache in memory.
|
||||
</string>
|
||||
<string name="feature_flags_category_title">Feature Flags</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -284,5 +284,14 @@
|
|||
a:summary="@string/settings.screen_lit_summary"
|
||||
a:title="@string/settings.screen_lit_title"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory a:title="@string/feature_flags_category_title">
|
||||
<CheckBoxPreference
|
||||
a:key="ff_new_image_loader"
|
||||
a:persistent="false"
|
||||
a:title="@string/feature_flags_image_loader_title"
|
||||
a:summary="@string/feature_flags_image_loader_description"
|
||||
/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
Loading…
Reference in New Issue