From 86ee29c3af9ea97df40bc0c91fc1cc745d3eddff Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Tue, 15 Oct 2024 16:29:14 +0530 Subject: [PATCH 01/17] Add support for custom signals --- .../remoteconfig/TestConstructorUtil.kt | 28 +++++------ .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +- .../FirebaseRemoteConfigIntegrationTest.java | 4 +- .../remoteconfig/FirebaseRemoteConfig.java | 28 +++++++++-- .../remoteconfig/RemoteConfigComponent.java | 19 ++++---- .../remoteconfig/RemoteConfigConstants.java | 4 +- .../internal/ConfigFetchHandler.java | 12 ++--- .../internal/ConfigFetchHttpClient.java | 10 +++- .../internal/ConfigRealtimeHandler.java | 4 +- .../internal/ConfigRealtimeHttpClient.java | 6 +-- ...ient.java => ConfigSharedPrefsClient.java} | 48 ++++++++++++++++++- .../FirebaseRemoteConfigInfoImpl.java | 2 +- .../FirebaseRemoteConfigTest.java | 8 ++-- .../RemoteConfigComponentTest.java | 8 ++-- .../remoteconfig/RemoteConfigTests.kt | 4 +- .../remoteconfig/TestConstructorUtil.kt | 28 +++++------ .../internal/ConfigFetchHandlerTest.java | 12 ++--- .../internal/ConfigFetchHttpClientTest.java | 13 ++++- ....java => ConfigSharedPrefsClientTest.java} | 47 ++++++++++++------ .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +- 20 files changed, 198 insertions(+), 95 deletions(-) rename firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/{ConfigMetadataClient.java => ConfigSharedPrefsClient.java} (87%) rename firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/{ConfigMetadataClientTest.java => ConfigSharedPrefsClientTest.java} (88%) diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt index e6167b5ab09..8ec1016ffc9 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,7 +23,7 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -31,19 +31,19 @@ import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigMetadataClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigSharedPrefsClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index bb525cf4090..aef2419e791 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,7 +32,7 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcMetadata = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java index 19900986b6f..3dd8807fe5c 100644 --- a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java +++ b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java @@ -35,7 +35,7 @@ import com.google.firebase.remoteconfig.internal.ConfigContainer; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.Date; @@ -60,7 +60,7 @@ public class FirebaseRemoteConfigIntegrationTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigMetadataClient metadataClient; + @Mock private ConfigSharedPrefsClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionHandler; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index b2e7e73d954..500817310c6 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -33,7 +33,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.DefaultsXmlParser; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; @@ -160,7 +160,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { private final ConfigCacheClient defaultConfigsCache; private final ConfigFetchHandler fetchHandler; private final ConfigGetParameterHandler getHandler; - private final ConfigMetadataClient frcMetadata; + private final ConfigSharedPrefsClient frcMetadata; private final FirebaseInstallationsApi firebaseInstallations; private final ConfigRealtimeHandler configRealtimeHandler; private final RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler; @@ -181,7 +181,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { ConfigCacheClient defaultConfigsCache, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigMetadataClient frcMetadata, + ConfigSharedPrefsClient frcMetadata, ConfigRealtimeHandler configRealtimeHandler, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { this.context = context; @@ -652,6 +652,28 @@ private Task setDefaultsWithStringsMapAsync(Map defaultsSt FirebaseExecutors.directExecutor(), (unusedContainer) -> Tasks.forResult(null)); } + /** + * Asynchronously changes the custom signals for this {@link FirebaseRemoteConfig} instance. + * + *

The values in {@code customSignals} must be one of the following types: + * + *

    + *
  • Long + *
  • String + *
+ * + * @param customSignals Map (key, value) of the custom signals to be set for the app instance + */ + @NonNull + public Task setCustomSignals(@NonNull Map customSignals) { + return Tasks.call( + executor, + () -> { + frcMetadata.setCustomSignals(customSignals); + return null; + }); + } + /** * Notifies the Firebase A/B Testing SDK about activated experiments. * diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java index 0835488f934..966de92001c 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java @@ -36,7 +36,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigStorageClient; import com.google.firebase.remoteconfig.internal.Personalization; @@ -166,7 +166,7 @@ public synchronized FirebaseRemoteConfig get(String namespace) { ConfigCacheClient fetchedCacheClient = getCacheClient(namespace, FETCH_FILE_NAME); ConfigCacheClient activatedCacheClient = getCacheClient(namespace, ACTIVATE_FILE_NAME); ConfigCacheClient defaultsCacheClient = getCacheClient(namespace, DEFAULTS_FILE_NAME); - ConfigMetadataClient metadataClient = getMetadataClient(context, appId, namespace); + ConfigSharedPrefsClient metadataClient = getMetadataClient(context, appId, namespace); ConfigGetParameterHandler getHandler = getGetHandler(activatedCacheClient, defaultsCacheClient); Personalization personalization = @@ -206,7 +206,7 @@ synchronized FirebaseRemoteConfig get( ConfigCacheClient defaultsClient, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient metadataClient, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { if (!frcNamespaceInstances.containsKey(namespace)) { FirebaseRemoteConfig in = @@ -254,7 +254,7 @@ private ConfigCacheClient getCacheClient(String namespace, String configStoreTyp @VisibleForTesting ConfigFetchHttpClient getFrcBackendApiClient( - String apiKey, String namespace, ConfigMetadataClient metadataClient) { + String apiKey, String namespace, ConfigSharedPrefsClient metadataClient) { String appId = firebaseApp.getOptions().getApplicationId(); return new ConfigFetchHttpClient( context, @@ -262,12 +262,13 @@ ConfigFetchHttpClient getFrcBackendApiClient( apiKey, namespace, /* connectTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds(), - /* readTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds()); + /* readTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds(), + /* customSignals= */ metadataClient.getCustomSignals()); } @VisibleForTesting synchronized ConfigFetchHandler getFetchHandler( - String namespace, ConfigCacheClient fetchedCacheClient, ConfigMetadataClient metadataClient) { + String namespace, ConfigCacheClient fetchedCacheClient, ConfigSharedPrefsClient metadataClient) { return new ConfigFetchHandler( firebaseInstallations, isPrimaryApp(firebaseApp) ? analyticsConnector : () -> null, @@ -287,7 +288,7 @@ synchronized ConfigRealtimeHandler getRealtime( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigMetadataClient metadataClient) { + ConfigSharedPrefsClient metadataClient) { return new ConfigRealtimeHandler( firebaseApp, firebaseInstallations, @@ -305,13 +306,13 @@ private ConfigGetParameterHandler getGetHandler( } @VisibleForTesting - static ConfigMetadataClient getMetadataClient(Context context, String appId, String namespace) { + static ConfigSharedPrefsClient getMetadataClient(Context context, String appId, String namespace) { String fileName = String.format( "%s_%s_%s_%s", FIREBASE_REMOTE_CONFIG_FILE_NAME_PREFIX, appId, namespace, PREFERENCES_FILE_NAME); SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); - return new ConfigMetadataClient(preferences); + return new ConfigSharedPrefsClient(preferences); } @Nullable diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java index 9c1a352dd0a..410306afd9c 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java @@ -51,7 +51,8 @@ public final class RemoteConfigConstants { RequestFieldKey.PACKAGE_NAME, RequestFieldKey.SDK_VERSION, RequestFieldKey.ANALYTICS_USER_PROPERTIES, - RequestFieldKey.FIRST_OPEN_TIME + RequestFieldKey.FIRST_OPEN_TIME, + RequestFieldKey.CUSTOM_SIGNALS }) @Retention(RetentionPolicy.SOURCE) public @interface RequestFieldKey { @@ -68,6 +69,7 @@ public final class RemoteConfigConstants { String SDK_VERSION = "sdkVersion"; String ANALYTICS_USER_PROPERTIES = "analyticsUserProperties"; String FIRST_OPEN_TIME = "firstOpenTime"; + String CUSTOM_SIGNALS = "customSignals"; } /** Keys of fields in the Fetch response body from the Firebase Remote Config server. */ diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java index 7c98589b153..fe0ba19e4bb 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java @@ -14,7 +14,7 @@ package com.google.firebase.remoteconfig.internal; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT; @@ -43,7 +43,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse.Status; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.HttpURLConnection; @@ -96,7 +96,7 @@ public class ConfigFetchHandler { private final Random randomGenerator; private final ConfigCacheClient fetchedConfigsCache; private final ConfigFetchHttpClient frcBackendApiClient; - private final ConfigMetadataClient frcMetadata; + private final ConfigSharedPrefsClient frcMetadata; private final Map customHttpHeaders; @@ -109,7 +109,7 @@ public ConfigFetchHandler( Random randomGenerator, ConfigCacheClient fetchedConfigsCache, ConfigFetchHttpClient frcBackendApiClient, - ConfigMetadataClient frcMetadata, + ConfigSharedPrefsClient frcMetadata, Map customHttpHeaders) { this.firebaseInstallations = firebaseInstallations; this.analyticsConnector = analyticsConnector; @@ -124,7 +124,7 @@ public ConfigFetchHandler( /** * Calls {@link #fetch(long)} with the {@link - * ConfigMetadataClient#getMinimumFetchIntervalInSeconds()}. + * ConfigSharedPrefsClient#getMinimumFetchIntervalInSeconds()}. */ public Task fetch() { return fetch(frcMetadata.getMinimumFetchIntervalInSeconds()); @@ -228,7 +228,7 @@ public Task fetchNowWithTypeAndAttemptNumber( * currently throttled. * *

If a fetch request is made to the backend, updates the last fetch status, last successful - * fetch time and {@link BackoffMetadata} in {@link ConfigMetadataClient}. + * fetch time and {@link BackoffMetadata} in {@link ConfigSharedPrefsClient}. */ private Task fetchIfCacheExpiredAndNotThrottled( Task cachedFetchConfigsTask, diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java index b1867347580..70dd1e19398 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java @@ -21,6 +21,7 @@ import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_VERSION; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.COUNTRY_CODE; +import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.FIRST_OPEN_TIME; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID_TOKEN; @@ -93,6 +94,7 @@ public class ConfigFetchHttpClient { private final String apiKey; private final String projectNumber; private final String namespace; + Map customSignalMap; private final long connectTimeoutInSeconds; private final long readTimeoutInSeconds; @@ -106,7 +108,8 @@ public ConfigFetchHttpClient( String apiKey, String namespace, long connectTimeoutInSeconds, - long readTimeoutInSeconds) { + long readTimeoutInSeconds, + Map customSignalMap) { this.context = context; this.appId = appId; this.apiKey = apiKey; @@ -114,6 +117,7 @@ public ConfigFetchHttpClient( this.namespace = namespace; this.connectTimeoutInSeconds = connectTimeoutInSeconds; this.readTimeoutInSeconds = readTimeoutInSeconds; + this.customSignalMap = customSignalMap; } /** Used to verify that the timeout is being set correctly. */ @@ -304,7 +308,7 @@ private JSONObject createFetchRequestBody( String installationAuthToken, Map analyticsUserProperties, Long firstOpenTime) - throws FirebaseRemoteConfigClientException { + throws FirebaseRemoteConfigClientException { Map requestBodyMap = new HashMap<>(); if (installationId == null) { @@ -347,6 +351,8 @@ private JSONObject createFetchRequestBody( requestBodyMap.put(ANALYTICS_USER_PROPERTIES, new JSONObject(analyticsUserProperties)); + requestBodyMap.put(CUSTOM_SIGNALS, new JSONObject(customSignalMap)); + if (firstOpenTime != null) { requestBodyMap.put(FIRST_OPEN_TIME, convertToISOString(firstOpenTime)); } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java index 53f89a71e8c..26dcbc9cce0 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java @@ -39,7 +39,7 @@ public class ConfigRealtimeHandler { private final ConfigCacheClient activatedCacheClient; private final Context context; private final String namespace; - private final ConfigMetadataClient metadataClient; + private final ConfigSharedPrefsClient metadataClient; private final ScheduledExecutorService scheduledExecutorService; public ConfigRealtimeHandler( @@ -49,7 +49,7 @@ public ConfigRealtimeHandler( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = new LinkedHashSet<>(); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java index ef0ef2defc5..a2f0a26b8c5 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java @@ -110,7 +110,7 @@ public class ConfigRealtimeHttpClient { private final String namespace; private final Random random; private final Clock clock; - private final ConfigMetadataClient metadataClient; + private final ConfigSharedPrefsClient metadataClient; public ConfigRealtimeHttpClient( FirebaseApp firebaseApp, @@ -120,7 +120,7 @@ public ConfigRealtimeHttpClient( Context context, String namespace, Set listeners, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = listeners; @@ -473,7 +473,7 @@ public void beginRealtimeHttpStream() { return; } - ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Date currentTime = new Date(clock.currentTimeMillis()); if (currentTime.before(backoffMetadata.getBackoffEndTime())) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java similarity index 87% rename from firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java rename to firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java index dddcb24bdb8..eb796493c0f 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java @@ -19,6 +19,7 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS; import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; +import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -29,8 +30,16 @@ import androidx.annotation.WorkerThread; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; + +import org.json.JSONException; +import org.json.JSONObject; + import java.lang.annotation.Retention; import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; /** * Client for handling Firebase Remote Config (FRC) metadata that is saved to disk and persisted @@ -38,7 +47,7 @@ * * @author Miraziz Yusupov */ -public class ConfigMetadataClient { +public class ConfigSharedPrefsClient { @Retention(SOURCE) @IntDef({ LAST_FETCH_STATUS_SUCCESS, @@ -80,12 +89,14 @@ public class ConfigMetadataClient { private final Object frcInfoLock; private final Object backoffMetadataLock; private final Object realtimeBackoffMetadataLock; + private final Object customSignalsLock; - public ConfigMetadataClient(SharedPreferences frcMetadata) { + public ConfigSharedPrefsClient(SharedPreferences frcMetadata) { this.frcMetadata = frcMetadata; this.frcInfoLock = new Object(); this.backoffMetadataLock = new Object(); this.realtimeBackoffMetadataLock = new Object(); + this.customSignalsLock = new Object(); } public long getFetchTimeoutInSeconds() { @@ -249,6 +260,39 @@ void setBackoffMetadata(int numFailedFetches, Date backoffEndTime) { } } + public void setCustomSignals(Map newCustomSignals) { + synchronized (customSignalsLock) { + // Retrieve existing custom signals + Map existingCustomSignals = getCustomSignals(); + + // Merge new signals with existing ones (new signals take precedence) + existingCustomSignals.putAll(newCustomSignals); + + // Ignore key-value pairs with null values, which signify unset signals. + existingCustomSignals.values().removeIf(Objects::isNull); + frcMetadata + .edit() + .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) + .commit(); + } + } + public Map getCustomSignals() { + String jsonString = frcMetadata.getString(CUSTOM_SIGNALS, "{}"); + try { + JSONObject existingCustomSignalsJson = new JSONObject(jsonString); + Map custom_signals = new HashMap<>(); + Iterator keys = existingCustomSignalsJson.keys(); + while (keys.hasNext()) { + String key = keys.next(); + custom_signals.put(key, existingCustomSignalsJson.get(key)); + } + return custom_signals; + } catch (JSONException e) { + return new HashMap<>(); + } + } + + void resetBackoff() { setBackoffMetadata(NO_FAILED_FETCHES, NO_BACKOFF_TIME); } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java index 15f0bb00028..4a16f7bf4e9 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java @@ -16,7 +16,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; /** * Impl class for FirebaseRemoteConfigInfo. diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 3618fd0ea27..1a7b81a2841 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -72,7 +72,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHttpClient; import com.google.firebase.remoteconfig.internal.FakeHttpURLConnection; @@ -155,7 +155,7 @@ public final class FirebaseRemoteConfigTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigMetadataClient metadataClient; + @Mock private ConfigSharedPrefsClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private ConfigAutoFetch mockConfigAutoFetch; @@ -192,7 +192,7 @@ public final class FirebaseRemoteConfigTest { private ConfigContainer realtimeFetchedContainer; private ConfigAutoFetch configAutoFetch; private ConfigRealtimeHttpClient configRealtimeHttpClient; - private ConfigMetadataClient realtimeMetadataClient; + private ConfigSharedPrefsClient realtimeMetadataClient; private FetchResponse firstFetchedContainerResponse; @@ -350,7 +350,7 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { mockRetryListener, scheduledExecutorService); realtimeMetadataClient = - new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); configRealtimeHttpClient = new ConfigRealtimeHttpClient( firebaseApp, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java index ebb69b491b6..d5cc72edf7c 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java @@ -39,7 +39,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import com.google.firebase.remoteconfig.interop.rollouts.RolloutsStateSubscriber; import java.util.Date; @@ -73,7 +73,7 @@ public class RemoteConfigComponentTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetParameterHandler; - @Mock private ConfigMetadataClient mockMetadataClient; + @Mock private ConfigSharedPrefsClient mockMetadataClient; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionsHandler; @Mock private RolloutsStateSubscriber mockRolloutsStateSubscriber; @@ -82,7 +82,7 @@ public class RemoteConfigComponentTest { private ExecutorService directExecutor; private ScheduledExecutorService scheduledExecutorService; private FirebaseApp defaultApp; - private ConfigMetadataClient metadataClient; + private ConfigSharedPrefsClient metadataClient; @Before public void setUp() { @@ -183,7 +183,7 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { public void registerRolloutsStateSubscriber_firebaseNamespace_callsSubscriptionHandler() { // Mock metadata client response since Realtime handler can't be mocked here. when(mockMetadataClient.getRealtimeBackoffMetadata()) - .thenReturn(new ConfigMetadataClient.RealtimeBackoffMetadata(0, new Date())); + .thenReturn(new ConfigSharedPrefsClient.RealtimeBackoffMetadata(0, new Date())); RemoteConfigComponent frcComponent = getNewFrcComponent(); FirebaseRemoteConfig instance = getFrcInstanceFromComponent(frcComponent, DEFAULT_NAMESPACE); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index 7624ee3827d..450ec30a532 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -29,7 +29,7 @@ import com.google.firebase.platforminfo.UserAgentPublisher import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After @@ -139,7 +139,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcMetadata = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt index e6167b5ab09..8ec1016ffc9 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,7 +23,7 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -31,19 +31,19 @@ import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigMetadataClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigSharedPrefsClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java index ed2781710fd..c383d505c19 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java @@ -29,9 +29,9 @@ import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FIRST_OPEN_TIME_KEY; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.HTTP_TOO_MANY_REQUESTS; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; @@ -70,7 +70,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; @@ -127,7 +127,7 @@ public class ConfigFetchHandlerTest { private Context context; @Mock private FirebaseInstallationsApi mockFirebaseInstallations; - private ConfigMetadataClient metadataClient; + private ConfigSharedPrefsClient metadataClient; private ConfigFetchHandler fetchHandler; @@ -143,7 +143,7 @@ public void setUp() throws Exception { context = ApplicationProvider.getApplicationContext(); mockClock = new MockClock(0L); metadataClient = - new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); loadBackendApiClient(); loadInstallationIdAndAuthToken(); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java index edbded6f79b..32b37820ccf 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java @@ -24,6 +24,7 @@ import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_VERSION; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.COUNTRY_CODE; +import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.FIRST_OPEN_TIME; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID_TOKEN; @@ -85,6 +86,10 @@ public class ConfigFetchHttpClientTest { "etag-" + PROJECT_NUMBER + "-" + DEFAULT_NAMESPACE + "-fetch-%d"; private static final String FIRST_ETAG = String.format(ETAG_FORMAT, 1); private static final String SECOND_ETAG = String.format(ETAG_FORMAT, 2); + private static final Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + "subscription", "premium", + "age", "20" + ); private Context context; private ConfigFetchHttpClient configFetchHttpClient; @@ -105,7 +110,8 @@ public void setUp() throws Exception { API_KEY, DEFAULT_NAMESPACE, /* connectTimeoutInSeconds= */ 10L, - /* readTimeoutInSeconds= */ 10L); + /* readTimeoutInSeconds= */ 10L, + /* customSignals= */ SAMPLE_CUSTOM_SIGNALS); hasChangeResponseBody = new JSONObject() @@ -238,6 +244,8 @@ public void fetch_setsAllElementsOfRequestBody_sendsRequestBodyToServer() throws assertThat(requestBody.get(FIRST_OPEN_TIME)).isEqualTo(firstOpenTimeIsoString); assertThat(requestBody.getJSONObject(ANALYTICS_USER_PROPERTIES).toString()) .isEqualTo(new JSONObject(customUserProperties).toString()); + assertThat(requestBody.getJSONObject(CUSTOM_SIGNALS).toString()) + .isEqualTo(new JSONObject(SAMPLE_CUSTOM_SIGNALS).toString()); } @Test @@ -316,7 +324,8 @@ public void fetch_setsTimeouts_urlConnectionHasTimeouts() throws Exception { API_KEY, DEFAULT_NAMESPACE, /* connectTimeoutInSeconds= */ 15L, - /* readTimeoutInSeconds= */ 20L); + /* readTimeoutInSeconds= */ 20L, + /* customSignals= */ SAMPLE_CUSTOM_SIGNALS); setServerResponseTo(noChangeResponseBody, SECOND_ETAG); fetch(FIRST_ETAG); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java similarity index 88% rename from firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java rename to firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java index e2c38df4a30..93f2ec7ac74 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java @@ -21,20 +21,24 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; import android.content.Context; import android.content.SharedPreferences; import androidx.test.core.app.ApplicationProvider; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; + +import java.util.Collections; import java.util.Date; +import java.util.Map; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,14 +46,14 @@ import org.robolectric.annotation.Config; /** - * Unit tests for the {@link ConfigMetadataClient}. + * Unit tests for the {@link ConfigSharedPrefsClient}. * * @author Miraziz Yusupov */ @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class ConfigMetadataClientTest { - private ConfigMetadataClient metadataClient; +public class ConfigSharedPrefsClientTest { + private ConfigSharedPrefsClient metadataClient; private FirebaseRemoteConfigSettings.Builder settingsBuilder; @Before @@ -60,7 +64,7 @@ public void setUp() { metadata.edit().clear().commit(); - metadataClient = new ConfigMetadataClient(metadata); + metadataClient = new ConfigSharedPrefsClient(metadata); settingsBuilder = new FirebaseRemoteConfigSettings.Builder(); } @@ -155,7 +159,7 @@ public void getLastTemplateVersion_isSet_returnsTemplateVersion() { @Test public void getRealtimeBackoffMetadata_isNotSet_returnsNoFailedStreamsAndNotThrottled() { - ConfigMetadataClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(defaultRealtimeBackoffMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); @@ -168,7 +172,7 @@ public void getRealtimeBackoffMetadata_hasValues_returnsValues() { Date backoffEndTime = new Date(1000L); metadataClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); - ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(backoffMetadata.getNumFailedStreams()).isEqualTo(numFailedStreams); @@ -180,7 +184,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.setRealtimeBackoffMetadata( /* numFailedStreams= */ 5, /* backoffEndTime= */ new Date(1000L)); - ConfigMetadataClient.RealtimeBackoffMetadata realtimeBackoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata realtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Preconditions.checkArgument(realtimeBackoffMetadata.getNumFailedStreams() != NO_FAILED_FETCHES); Preconditions.checkArgument( @@ -188,7 +192,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.resetRealtimeBackoff(); - ConfigMetadataClient.RealtimeBackoffMetadata resetMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata resetMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(resetMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); assertThat(resetMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); @@ -349,4 +353,19 @@ public void clear_hasSetValues_clearsAll() { assertThat(info.getConfigSettings().getMinimumFetchIntervalInSeconds()) .isEqualTo(DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS); } + + @Test + public void getCustomSignals_isNotSet_returnsEmptyMap() { + assertThat(metadataClient.getCustomSignals()).isEqualTo(Collections.emptyMap()); + } + + @Test + public void getCustomSignals_isSet_returnsCustomSignals() { + Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + "subscription", "premium", + "age", "20" + ); + metadataClient.setCustomSignals(SAMPLE_CUSTOM_SIGNALS); + assertThat(metadataClient.getCustomSignals()).isEqualTo(SAMPLE_CUSTOM_SIGNALS); + } } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index c11ea869fbf..ad9daae11a6 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,7 +32,7 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcMetadata = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) From b241027638526a3e1d05aa5eed4c3ea94913f071 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Tue, 15 Oct 2024 16:29:14 +0530 Subject: [PATCH 02/17] Add support for custom signals --- .../remoteconfig/TestConstructorUtil.kt | 28 +++++------ .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +- .../FirebaseRemoteConfigIntegrationTest.java | 4 +- .../remoteconfig/FirebaseRemoteConfig.java | 28 +++++++++-- .../remoteconfig/RemoteConfigComponent.java | 19 ++++---- .../remoteconfig/RemoteConfigConstants.java | 4 +- .../internal/ConfigFetchHandler.java | 12 ++--- .../internal/ConfigFetchHttpClient.java | 10 +++- .../internal/ConfigRealtimeHandler.java | 4 +- .../internal/ConfigRealtimeHttpClient.java | 6 +-- ...ient.java => ConfigSharedPrefsClient.java} | 48 ++++++++++++++++++- .../FirebaseRemoteConfigInfoImpl.java | 2 +- .../FirebaseRemoteConfigTest.java | 8 ++-- .../RemoteConfigComponentTest.java | 8 ++-- .../remoteconfig/RemoteConfigTests.kt | 4 +- .../remoteconfig/TestConstructorUtil.kt | 28 +++++------ .../internal/ConfigFetchHandlerTest.java | 12 ++--- .../internal/ConfigFetchHttpClientTest.java | 13 ++++- ....java => ConfigSharedPrefsClientTest.java} | 47 ++++++++++++------ .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +- 20 files changed, 198 insertions(+), 95 deletions(-) rename firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/{ConfigMetadataClient.java => ConfigSharedPrefsClient.java} (87%) rename firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/{ConfigMetadataClientTest.java => ConfigSharedPrefsClientTest.java} (88%) diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt index e6167b5ab09..8ec1016ffc9 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,7 +23,7 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -31,19 +31,19 @@ import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigMetadataClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigSharedPrefsClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index bb525cf4090..aef2419e791 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,7 +32,7 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcMetadata = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java index 19900986b6f..3dd8807fe5c 100644 --- a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java +++ b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java @@ -35,7 +35,7 @@ import com.google.firebase.remoteconfig.internal.ConfigContainer; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.Date; @@ -60,7 +60,7 @@ public class FirebaseRemoteConfigIntegrationTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigMetadataClient metadataClient; + @Mock private ConfigSharedPrefsClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionHandler; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index b2e7e73d954..500817310c6 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -33,7 +33,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.DefaultsXmlParser; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; @@ -160,7 +160,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { private final ConfigCacheClient defaultConfigsCache; private final ConfigFetchHandler fetchHandler; private final ConfigGetParameterHandler getHandler; - private final ConfigMetadataClient frcMetadata; + private final ConfigSharedPrefsClient frcMetadata; private final FirebaseInstallationsApi firebaseInstallations; private final ConfigRealtimeHandler configRealtimeHandler; private final RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler; @@ -181,7 +181,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { ConfigCacheClient defaultConfigsCache, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigMetadataClient frcMetadata, + ConfigSharedPrefsClient frcMetadata, ConfigRealtimeHandler configRealtimeHandler, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { this.context = context; @@ -652,6 +652,28 @@ private Task setDefaultsWithStringsMapAsync(Map defaultsSt FirebaseExecutors.directExecutor(), (unusedContainer) -> Tasks.forResult(null)); } + /** + * Asynchronously changes the custom signals for this {@link FirebaseRemoteConfig} instance. + * + *

The values in {@code customSignals} must be one of the following types: + * + *

    + *
  • Long + *
  • String + *
+ * + * @param customSignals Map (key, value) of the custom signals to be set for the app instance + */ + @NonNull + public Task setCustomSignals(@NonNull Map customSignals) { + return Tasks.call( + executor, + () -> { + frcMetadata.setCustomSignals(customSignals); + return null; + }); + } + /** * Notifies the Firebase A/B Testing SDK about activated experiments. * diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java index 0835488f934..966de92001c 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java @@ -36,7 +36,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigStorageClient; import com.google.firebase.remoteconfig.internal.Personalization; @@ -166,7 +166,7 @@ public synchronized FirebaseRemoteConfig get(String namespace) { ConfigCacheClient fetchedCacheClient = getCacheClient(namespace, FETCH_FILE_NAME); ConfigCacheClient activatedCacheClient = getCacheClient(namespace, ACTIVATE_FILE_NAME); ConfigCacheClient defaultsCacheClient = getCacheClient(namespace, DEFAULTS_FILE_NAME); - ConfigMetadataClient metadataClient = getMetadataClient(context, appId, namespace); + ConfigSharedPrefsClient metadataClient = getMetadataClient(context, appId, namespace); ConfigGetParameterHandler getHandler = getGetHandler(activatedCacheClient, defaultsCacheClient); Personalization personalization = @@ -206,7 +206,7 @@ synchronized FirebaseRemoteConfig get( ConfigCacheClient defaultsClient, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient metadataClient, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { if (!frcNamespaceInstances.containsKey(namespace)) { FirebaseRemoteConfig in = @@ -254,7 +254,7 @@ private ConfigCacheClient getCacheClient(String namespace, String configStoreTyp @VisibleForTesting ConfigFetchHttpClient getFrcBackendApiClient( - String apiKey, String namespace, ConfigMetadataClient metadataClient) { + String apiKey, String namespace, ConfigSharedPrefsClient metadataClient) { String appId = firebaseApp.getOptions().getApplicationId(); return new ConfigFetchHttpClient( context, @@ -262,12 +262,13 @@ ConfigFetchHttpClient getFrcBackendApiClient( apiKey, namespace, /* connectTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds(), - /* readTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds()); + /* readTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds(), + /* customSignals= */ metadataClient.getCustomSignals()); } @VisibleForTesting synchronized ConfigFetchHandler getFetchHandler( - String namespace, ConfigCacheClient fetchedCacheClient, ConfigMetadataClient metadataClient) { + String namespace, ConfigCacheClient fetchedCacheClient, ConfigSharedPrefsClient metadataClient) { return new ConfigFetchHandler( firebaseInstallations, isPrimaryApp(firebaseApp) ? analyticsConnector : () -> null, @@ -287,7 +288,7 @@ synchronized ConfigRealtimeHandler getRealtime( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigMetadataClient metadataClient) { + ConfigSharedPrefsClient metadataClient) { return new ConfigRealtimeHandler( firebaseApp, firebaseInstallations, @@ -305,13 +306,13 @@ private ConfigGetParameterHandler getGetHandler( } @VisibleForTesting - static ConfigMetadataClient getMetadataClient(Context context, String appId, String namespace) { + static ConfigSharedPrefsClient getMetadataClient(Context context, String appId, String namespace) { String fileName = String.format( "%s_%s_%s_%s", FIREBASE_REMOTE_CONFIG_FILE_NAME_PREFIX, appId, namespace, PREFERENCES_FILE_NAME); SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); - return new ConfigMetadataClient(preferences); + return new ConfigSharedPrefsClient(preferences); } @Nullable diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java index 9c1a352dd0a..410306afd9c 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigConstants.java @@ -51,7 +51,8 @@ public final class RemoteConfigConstants { RequestFieldKey.PACKAGE_NAME, RequestFieldKey.SDK_VERSION, RequestFieldKey.ANALYTICS_USER_PROPERTIES, - RequestFieldKey.FIRST_OPEN_TIME + RequestFieldKey.FIRST_OPEN_TIME, + RequestFieldKey.CUSTOM_SIGNALS }) @Retention(RetentionPolicy.SOURCE) public @interface RequestFieldKey { @@ -68,6 +69,7 @@ public final class RemoteConfigConstants { String SDK_VERSION = "sdkVersion"; String ANALYTICS_USER_PROPERTIES = "analyticsUserProperties"; String FIRST_OPEN_TIME = "firstOpenTime"; + String CUSTOM_SIGNALS = "customSignals"; } /** Keys of fields in the Fetch response body from the Firebase Remote Config server. */ diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java index 7c98589b153..fe0ba19e4bb 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java @@ -14,7 +14,7 @@ package com.google.firebase.remoteconfig.internal; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT; @@ -43,7 +43,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse.Status; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.HttpURLConnection; @@ -96,7 +96,7 @@ public class ConfigFetchHandler { private final Random randomGenerator; private final ConfigCacheClient fetchedConfigsCache; private final ConfigFetchHttpClient frcBackendApiClient; - private final ConfigMetadataClient frcMetadata; + private final ConfigSharedPrefsClient frcMetadata; private final Map customHttpHeaders; @@ -109,7 +109,7 @@ public ConfigFetchHandler( Random randomGenerator, ConfigCacheClient fetchedConfigsCache, ConfigFetchHttpClient frcBackendApiClient, - ConfigMetadataClient frcMetadata, + ConfigSharedPrefsClient frcMetadata, Map customHttpHeaders) { this.firebaseInstallations = firebaseInstallations; this.analyticsConnector = analyticsConnector; @@ -124,7 +124,7 @@ public ConfigFetchHandler( /** * Calls {@link #fetch(long)} with the {@link - * ConfigMetadataClient#getMinimumFetchIntervalInSeconds()}. + * ConfigSharedPrefsClient#getMinimumFetchIntervalInSeconds()}. */ public Task fetch() { return fetch(frcMetadata.getMinimumFetchIntervalInSeconds()); @@ -228,7 +228,7 @@ public Task fetchNowWithTypeAndAttemptNumber( * currently throttled. * *

If a fetch request is made to the backend, updates the last fetch status, last successful - * fetch time and {@link BackoffMetadata} in {@link ConfigMetadataClient}. + * fetch time and {@link BackoffMetadata} in {@link ConfigSharedPrefsClient}. */ private Task fetchIfCacheExpiredAndNotThrottled( Task cachedFetchConfigsTask, diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java index b1867347580..70dd1e19398 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java @@ -21,6 +21,7 @@ import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_VERSION; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.COUNTRY_CODE; +import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.FIRST_OPEN_TIME; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID_TOKEN; @@ -93,6 +94,7 @@ public class ConfigFetchHttpClient { private final String apiKey; private final String projectNumber; private final String namespace; + Map customSignalMap; private final long connectTimeoutInSeconds; private final long readTimeoutInSeconds; @@ -106,7 +108,8 @@ public ConfigFetchHttpClient( String apiKey, String namespace, long connectTimeoutInSeconds, - long readTimeoutInSeconds) { + long readTimeoutInSeconds, + Map customSignalMap) { this.context = context; this.appId = appId; this.apiKey = apiKey; @@ -114,6 +117,7 @@ public ConfigFetchHttpClient( this.namespace = namespace; this.connectTimeoutInSeconds = connectTimeoutInSeconds; this.readTimeoutInSeconds = readTimeoutInSeconds; + this.customSignalMap = customSignalMap; } /** Used to verify that the timeout is being set correctly. */ @@ -304,7 +308,7 @@ private JSONObject createFetchRequestBody( String installationAuthToken, Map analyticsUserProperties, Long firstOpenTime) - throws FirebaseRemoteConfigClientException { + throws FirebaseRemoteConfigClientException { Map requestBodyMap = new HashMap<>(); if (installationId == null) { @@ -347,6 +351,8 @@ private JSONObject createFetchRequestBody( requestBodyMap.put(ANALYTICS_USER_PROPERTIES, new JSONObject(analyticsUserProperties)); + requestBodyMap.put(CUSTOM_SIGNALS, new JSONObject(customSignalMap)); + if (firstOpenTime != null) { requestBodyMap.put(FIRST_OPEN_TIME, convertToISOString(firstOpenTime)); } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java index 53f89a71e8c..26dcbc9cce0 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java @@ -39,7 +39,7 @@ public class ConfigRealtimeHandler { private final ConfigCacheClient activatedCacheClient; private final Context context; private final String namespace; - private final ConfigMetadataClient metadataClient; + private final ConfigSharedPrefsClient metadataClient; private final ScheduledExecutorService scheduledExecutorService; public ConfigRealtimeHandler( @@ -49,7 +49,7 @@ public ConfigRealtimeHandler( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = new LinkedHashSet<>(); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java index ef0ef2defc5..a2f0a26b8c5 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java @@ -110,7 +110,7 @@ public class ConfigRealtimeHttpClient { private final String namespace; private final Random random; private final Clock clock; - private final ConfigMetadataClient metadataClient; + private final ConfigSharedPrefsClient metadataClient; public ConfigRealtimeHttpClient( FirebaseApp firebaseApp, @@ -120,7 +120,7 @@ public ConfigRealtimeHttpClient( Context context, String namespace, Set listeners, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = listeners; @@ -473,7 +473,7 @@ public void beginRealtimeHttpStream() { return; } - ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Date currentTime = new Date(clock.currentTimeMillis()); if (currentTime.before(backoffMetadata.getBackoffEndTime())) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java similarity index 87% rename from firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java rename to firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java index dddcb24bdb8..eb796493c0f 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java @@ -19,6 +19,7 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS; import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; +import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -29,8 +30,16 @@ import androidx.annotation.WorkerThread; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; + +import org.json.JSONException; +import org.json.JSONObject; + import java.lang.annotation.Retention; import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; /** * Client for handling Firebase Remote Config (FRC) metadata that is saved to disk and persisted @@ -38,7 +47,7 @@ * * @author Miraziz Yusupov */ -public class ConfigMetadataClient { +public class ConfigSharedPrefsClient { @Retention(SOURCE) @IntDef({ LAST_FETCH_STATUS_SUCCESS, @@ -80,12 +89,14 @@ public class ConfigMetadataClient { private final Object frcInfoLock; private final Object backoffMetadataLock; private final Object realtimeBackoffMetadataLock; + private final Object customSignalsLock; - public ConfigMetadataClient(SharedPreferences frcMetadata) { + public ConfigSharedPrefsClient(SharedPreferences frcMetadata) { this.frcMetadata = frcMetadata; this.frcInfoLock = new Object(); this.backoffMetadataLock = new Object(); this.realtimeBackoffMetadataLock = new Object(); + this.customSignalsLock = new Object(); } public long getFetchTimeoutInSeconds() { @@ -249,6 +260,39 @@ void setBackoffMetadata(int numFailedFetches, Date backoffEndTime) { } } + public void setCustomSignals(Map newCustomSignals) { + synchronized (customSignalsLock) { + // Retrieve existing custom signals + Map existingCustomSignals = getCustomSignals(); + + // Merge new signals with existing ones (new signals take precedence) + existingCustomSignals.putAll(newCustomSignals); + + // Ignore key-value pairs with null values, which signify unset signals. + existingCustomSignals.values().removeIf(Objects::isNull); + frcMetadata + .edit() + .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) + .commit(); + } + } + public Map getCustomSignals() { + String jsonString = frcMetadata.getString(CUSTOM_SIGNALS, "{}"); + try { + JSONObject existingCustomSignalsJson = new JSONObject(jsonString); + Map custom_signals = new HashMap<>(); + Iterator keys = existingCustomSignalsJson.keys(); + while (keys.hasNext()) { + String key = keys.next(); + custom_signals.put(key, existingCustomSignalsJson.get(key)); + } + return custom_signals; + } catch (JSONException e) { + return new HashMap<>(); + } + } + + void resetBackoff() { setBackoffMetadata(NO_FAILED_FETCHES, NO_BACKOFF_TIME); } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java index 15f0bb00028..4a16f7bf4e9 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java @@ -16,7 +16,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; /** * Impl class for FirebaseRemoteConfigInfo. diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 81f292a4c2b..7341f8ea296 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -72,7 +72,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHttpClient; import com.google.firebase.remoteconfig.internal.FakeHttpURLConnection; @@ -155,7 +155,7 @@ public final class FirebaseRemoteConfigTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigMetadataClient metadataClient; + @Mock private ConfigSharedPrefsClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private ConfigAutoFetch mockConfigAutoFetch; @@ -192,7 +192,7 @@ public final class FirebaseRemoteConfigTest { private ConfigContainer realtimeFetchedContainer; private ConfigAutoFetch configAutoFetch; private ConfigRealtimeHttpClient configRealtimeHttpClient; - private ConfigMetadataClient realtimeMetadataClient; + private ConfigSharedPrefsClient realtimeMetadataClient; private FetchResponse firstFetchedContainerResponse; @@ -350,7 +350,7 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { mockRetryListener, scheduledExecutorService); realtimeMetadataClient = - new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); configRealtimeHttpClient = new ConfigRealtimeHttpClient( firebaseApp, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java index c6869267a4d..7511ffe4a63 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java @@ -39,7 +39,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import com.google.firebase.remoteconfig.interop.rollouts.RolloutsStateSubscriber; import java.util.Date; @@ -73,7 +73,7 @@ public class RemoteConfigComponentTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetParameterHandler; - @Mock private ConfigMetadataClient mockMetadataClient; + @Mock private ConfigSharedPrefsClient mockMetadataClient; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionsHandler; @Mock private RolloutsStateSubscriber mockRolloutsStateSubscriber; @@ -82,7 +82,7 @@ public class RemoteConfigComponentTest { private ExecutorService directExecutor; private ScheduledExecutorService scheduledExecutorService; private FirebaseApp defaultApp; - private ConfigMetadataClient metadataClient; + private ConfigSharedPrefsClient metadataClient; @Before public void setUp() { @@ -183,7 +183,7 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { public void registerRolloutsStateSubscriber_firebaseNamespace_callsSubscriptionHandler() { // Mock metadata client response since Realtime handler can't be mocked here. when(mockMetadataClient.getRealtimeBackoffMetadata()) - .thenReturn(new ConfigMetadataClient.RealtimeBackoffMetadata(0, new Date())); + .thenReturn(new ConfigSharedPrefsClient.RealtimeBackoffMetadata(0, new Date())); RemoteConfigComponent frcComponent = getNewFrcComponentWithoutLoadingDefault(); FirebaseRemoteConfig instance = getFrcInstanceFromComponent(frcComponent, DEFAULT_NAMESPACE); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index 7624ee3827d..450ec30a532 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -29,7 +29,7 @@ import com.google.firebase.platforminfo.UserAgentPublisher import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After @@ -139,7 +139,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcMetadata = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt index e6167b5ab09..8ec1016ffc9 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,7 +23,7 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -31,19 +31,19 @@ import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigMetadataClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigSharedPrefsClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java index ed2781710fd..c383d505c19 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java @@ -29,9 +29,9 @@ import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FIRST_OPEN_TIME_KEY; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.HTTP_TOO_MANY_REQUESTS; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; @@ -70,7 +70,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; @@ -127,7 +127,7 @@ public class ConfigFetchHandlerTest { private Context context; @Mock private FirebaseInstallationsApi mockFirebaseInstallations; - private ConfigMetadataClient metadataClient; + private ConfigSharedPrefsClient metadataClient; private ConfigFetchHandler fetchHandler; @@ -143,7 +143,7 @@ public void setUp() throws Exception { context = ApplicationProvider.getApplicationContext(); mockClock = new MockClock(0L); metadataClient = - new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); loadBackendApiClient(); loadInstallationIdAndAuthToken(); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java index edbded6f79b..32b37820ccf 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java @@ -24,6 +24,7 @@ import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.APP_VERSION; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.COUNTRY_CODE; +import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.FIRST_OPEN_TIME; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.INSTANCE_ID_TOKEN; @@ -85,6 +86,10 @@ public class ConfigFetchHttpClientTest { "etag-" + PROJECT_NUMBER + "-" + DEFAULT_NAMESPACE + "-fetch-%d"; private static final String FIRST_ETAG = String.format(ETAG_FORMAT, 1); private static final String SECOND_ETAG = String.format(ETAG_FORMAT, 2); + private static final Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + "subscription", "premium", + "age", "20" + ); private Context context; private ConfigFetchHttpClient configFetchHttpClient; @@ -105,7 +110,8 @@ public void setUp() throws Exception { API_KEY, DEFAULT_NAMESPACE, /* connectTimeoutInSeconds= */ 10L, - /* readTimeoutInSeconds= */ 10L); + /* readTimeoutInSeconds= */ 10L, + /* customSignals= */ SAMPLE_CUSTOM_SIGNALS); hasChangeResponseBody = new JSONObject() @@ -238,6 +244,8 @@ public void fetch_setsAllElementsOfRequestBody_sendsRequestBodyToServer() throws assertThat(requestBody.get(FIRST_OPEN_TIME)).isEqualTo(firstOpenTimeIsoString); assertThat(requestBody.getJSONObject(ANALYTICS_USER_PROPERTIES).toString()) .isEqualTo(new JSONObject(customUserProperties).toString()); + assertThat(requestBody.getJSONObject(CUSTOM_SIGNALS).toString()) + .isEqualTo(new JSONObject(SAMPLE_CUSTOM_SIGNALS).toString()); } @Test @@ -316,7 +324,8 @@ public void fetch_setsTimeouts_urlConnectionHasTimeouts() throws Exception { API_KEY, DEFAULT_NAMESPACE, /* connectTimeoutInSeconds= */ 15L, - /* readTimeoutInSeconds= */ 20L); + /* readTimeoutInSeconds= */ 20L, + /* customSignals= */ SAMPLE_CUSTOM_SIGNALS); setServerResponseTo(noChangeResponseBody, SECOND_ETAG); fetch(FIRST_ETAG); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java similarity index 88% rename from firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java rename to firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java index e2c38df4a30..93f2ec7ac74 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java @@ -21,20 +21,24 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; import android.content.Context; import android.content.SharedPreferences; import androidx.test.core.app.ApplicationProvider; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; + +import java.util.Collections; import java.util.Date; +import java.util.Map; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,14 +46,14 @@ import org.robolectric.annotation.Config; /** - * Unit tests for the {@link ConfigMetadataClient}. + * Unit tests for the {@link ConfigSharedPrefsClient}. * * @author Miraziz Yusupov */ @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class ConfigMetadataClientTest { - private ConfigMetadataClient metadataClient; +public class ConfigSharedPrefsClientTest { + private ConfigSharedPrefsClient metadataClient; private FirebaseRemoteConfigSettings.Builder settingsBuilder; @Before @@ -60,7 +64,7 @@ public void setUp() { metadata.edit().clear().commit(); - metadataClient = new ConfigMetadataClient(metadata); + metadataClient = new ConfigSharedPrefsClient(metadata); settingsBuilder = new FirebaseRemoteConfigSettings.Builder(); } @@ -155,7 +159,7 @@ public void getLastTemplateVersion_isSet_returnsTemplateVersion() { @Test public void getRealtimeBackoffMetadata_isNotSet_returnsNoFailedStreamsAndNotThrottled() { - ConfigMetadataClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(defaultRealtimeBackoffMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); @@ -168,7 +172,7 @@ public void getRealtimeBackoffMetadata_hasValues_returnsValues() { Date backoffEndTime = new Date(1000L); metadataClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); - ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(backoffMetadata.getNumFailedStreams()).isEqualTo(numFailedStreams); @@ -180,7 +184,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.setRealtimeBackoffMetadata( /* numFailedStreams= */ 5, /* backoffEndTime= */ new Date(1000L)); - ConfigMetadataClient.RealtimeBackoffMetadata realtimeBackoffMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata realtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Preconditions.checkArgument(realtimeBackoffMetadata.getNumFailedStreams() != NO_FAILED_FETCHES); Preconditions.checkArgument( @@ -188,7 +192,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.resetRealtimeBackoff(); - ConfigMetadataClient.RealtimeBackoffMetadata resetMetadata = + ConfigSharedPrefsClient.RealtimeBackoffMetadata resetMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(resetMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); assertThat(resetMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); @@ -349,4 +353,19 @@ public void clear_hasSetValues_clearsAll() { assertThat(info.getConfigSettings().getMinimumFetchIntervalInSeconds()) .isEqualTo(DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS); } + + @Test + public void getCustomSignals_isNotSet_returnsEmptyMap() { + assertThat(metadataClient.getCustomSignals()).isEqualTo(Collections.emptyMap()); + } + + @Test + public void getCustomSignals_isSet_returnsCustomSignals() { + Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + "subscription", "premium", + "age", "20" + ); + metadataClient.setCustomSignals(SAMPLE_CUSTOM_SIGNALS); + assertThat(metadataClient.getCustomSignals()).isEqualTo(SAMPLE_CUSTOM_SIGNALS); + } } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index c11ea869fbf..ad9daae11a6 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,7 +32,7 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcMetadata = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) From ff596aee3787af11da55565636842ffbd797ec99 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Fri, 25 Oct 2024 20:44:56 +0530 Subject: [PATCH 03/17] Fix lint and build errors. --- .../FirebaseRemoteConfigIntegrationTest.java | 2 +- .../remoteconfig/FirebaseRemoteConfig.java | 12 +++---- .../remoteconfig/RemoteConfigComponent.java | 9 ++++-- .../internal/ConfigFetchHttpClient.java | 2 +- .../internal/ConfigSharedPrefsClient.java | 32 +++++++++++-------- .../FirebaseRemoteConfigTest.java | 5 +-- .../remoteconfig/RemoteConfigTests.kt | 2 +- .../remoteconfig/TestConstructorUtil.kt | 28 ++++++++-------- .../internal/ConfigFetchHandlerTest.java | 3 +- .../internal/ConfigFetchHttpClientTest.java | 8 ++--- .../internal/ConfigSharedPrefsClientTest.java | 7 ++-- .../remoteconfig/ktx/RemoteConfigTests.kt | 2 +- 12 files changed, 60 insertions(+), 52 deletions(-) diff --git a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java index 3dd8807fe5c..adb5d2f4ea8 100644 --- a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java +++ b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java @@ -35,8 +35,8 @@ import com.google.firebase.remoteconfig.internal.ConfigContainer; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.Date; import java.util.HashMap; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index 500817310c6..ea394551852 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -33,8 +33,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.DefaultsXmlParser; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.ArrayList; @@ -667,11 +667,11 @@ private Task setDefaultsWithStringsMapAsync(Map defaultsSt @NonNull public Task setCustomSignals(@NonNull Map customSignals) { return Tasks.call( - executor, - () -> { - frcMetadata.setCustomSignals(customSignals); - return null; - }); + executor, + () -> { + frcMetadata.setCustomSignals(customSignals); + return null; + }); } /** diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java index 966de92001c..36eb5650541 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java @@ -36,8 +36,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigStorageClient; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateFactory; @@ -268,7 +268,9 @@ ConfigFetchHttpClient getFrcBackendApiClient( @VisibleForTesting synchronized ConfigFetchHandler getFetchHandler( - String namespace, ConfigCacheClient fetchedCacheClient, ConfigSharedPrefsClient metadataClient) { + String namespace, + ConfigCacheClient fetchedCacheClient, + ConfigSharedPrefsClient metadataClient) { return new ConfigFetchHandler( firebaseInstallations, isPrimaryApp(firebaseApp) ? analyticsConnector : () -> null, @@ -306,7 +308,8 @@ private ConfigGetParameterHandler getGetHandler( } @VisibleForTesting - static ConfigSharedPrefsClient getMetadataClient(Context context, String appId, String namespace) { + static ConfigSharedPrefsClient getMetadataClient( + Context context, String appId, String namespace) { String fileName = String.format( "%s_%s_%s_%s", diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java index 70dd1e19398..3b8cf307dd7 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java @@ -308,7 +308,7 @@ private JSONObject createFetchRequestBody( String installationAuthToken, Map analyticsUserProperties, Long firstOpenTime) - throws FirebaseRemoteConfigClientException { + throws FirebaseRemoteConfigClientException { Map requestBodyMap = new HashMap<>(); if (installationId == null) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java index eb796493c0f..29f2f2ad1df 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java @@ -30,16 +30,13 @@ import androidx.annotation.WorkerThread; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; - -import org.json.JSONException; -import org.json.JSONObject; - import java.lang.annotation.Retention; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.Objects; +import org.json.JSONException; +import org.json.JSONObject; /** * Client for handling Firebase Remote Config (FRC) metadata that is saved to disk and persisted @@ -265,17 +262,25 @@ public void setCustomSignals(Map newCustomSignals) { // Retrieve existing custom signals Map existingCustomSignals = getCustomSignals(); - // Merge new signals with existing ones (new signals take precedence) - existingCustomSignals.putAll(newCustomSignals); - - // Ignore key-value pairs with null values, which signify unset signals. - existingCustomSignals.values().removeIf(Objects::isNull); + for (Map.Entry entry : newCustomSignals.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + // Merge new signals with existing ones, overwriting existing keys. + // Also, remove entries where the new value is null. + if (value != null) { + existingCustomSignals.put(key, value); + } else { + existingCustomSignals.remove(key); + } + } frcMetadata - .edit() - .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) - .commit(); + .edit() + .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) + .commit(); } } + public Map getCustomSignals() { String jsonString = frcMetadata.getString(CUSTOM_SIGNALS, "{}"); try { @@ -292,7 +297,6 @@ public Map getCustomSignals() { } } - void resetBackoff() { setBackoffMetadata(NO_FAILED_FETCHES, NO_BACKOFF_TIME); } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 7341f8ea296..187fd79a4a7 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -72,9 +72,9 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHttpClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.FakeHttpURLConnection; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; @@ -350,7 +350,8 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { mockRetryListener, scheduledExecutorService); realtimeMetadataClient = - new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient( + context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); configRealtimeHttpClient = new ConfigRealtimeHttpClient( firebaseApp, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index 450ec30a532..d7646965513 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -29,8 +29,8 @@ import com.google.firebase.platforminfo.UserAgentPublisher import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt index 8ec1016ffc9..16447dbc5ad 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,27 +23,27 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigSharedPrefsClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigSharedPrefsClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java index c383d505c19..3269b18dd6f 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java @@ -143,7 +143,8 @@ public void setUp() throws Exception { context = ApplicationProvider.getApplicationContext(); mockClock = new MockClock(0L); metadataClient = - new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient( + context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); loadBackendApiClient(); loadInstallationIdAndAuthToken(); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java index 32b37820ccf..1a6426482d8 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java @@ -86,10 +86,10 @@ public class ConfigFetchHttpClientTest { "etag-" + PROJECT_NUMBER + "-" + DEFAULT_NAMESPACE + "-fetch-%d"; private static final String FIRST_ETAG = String.format(ETAG_FORMAT, 1); private static final String SECOND_ETAG = String.format(ETAG_FORMAT, 2); - private static final Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + private static final Map SAMPLE_CUSTOM_SIGNALS = + ImmutableMap.of( "subscription", "premium", - "age", "20" - ); + "age", "20"); private Context context; private ConfigFetchHttpClient configFetchHttpClient; @@ -245,7 +245,7 @@ public void fetch_setsAllElementsOfRequestBody_sendsRequestBodyToServer() throws assertThat(requestBody.getJSONObject(ANALYTICS_USER_PROPERTIES).toString()) .isEqualTo(new JSONObject(customUserProperties).toString()); assertThat(requestBody.getJSONObject(CUSTOM_SIGNALS).toString()) - .isEqualTo(new JSONObject(SAMPLE_CUSTOM_SIGNALS).toString()); + .isEqualTo(new JSONObject(SAMPLE_CUSTOM_SIGNALS).toString()); } @Test diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java index 93f2ec7ac74..a78b345c71a 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java @@ -35,7 +35,6 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; - import java.util.Collections; import java.util.Date; import java.util.Map; @@ -361,10 +360,10 @@ public void getCustomSignals_isNotSet_returnsEmptyMap() { @Test public void getCustomSignals_isSet_returnsCustomSignals() { - Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + Map SAMPLE_CUSTOM_SIGNALS = + ImmutableMap.of( "subscription", "premium", - "age", "20" - ); + "age", "20"); metadataClient.setCustomSignals(SAMPLE_CUSTOM_SIGNALS); assertThat(metadataClient.getCustomSignals()).isEqualTo(SAMPLE_CUSTOM_SIGNALS); } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index ad9daae11a6..30bef10ac47 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,8 +32,8 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before From 2a678f6d6a675b52842b67b9e50e57a8b5b3f897 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Fri, 25 Oct 2024 20:44:56 +0530 Subject: [PATCH 04/17] Fix lint and build errors. --- .../remoteconfig/TestConstructorUtil.kt | 28 ++++++++-------- .../remoteconfig/ktx/RemoteConfigTests.kt | 2 +- .../FirebaseRemoteConfigIntegrationTest.java | 2 +- .../remoteconfig/FirebaseRemoteConfig.java | 12 +++---- .../remoteconfig/RemoteConfigComponent.java | 9 ++++-- .../internal/ConfigFetchHttpClient.java | 2 +- .../internal/ConfigSharedPrefsClient.java | 32 +++++++++++-------- .../FirebaseRemoteConfigTest.java | 5 +-- .../remoteconfig/RemoteConfigTests.kt | 2 +- .../remoteconfig/TestConstructorUtil.kt | 28 ++++++++-------- .../internal/ConfigFetchHandlerTest.java | 3 +- .../internal/ConfigFetchHttpClientTest.java | 8 ++--- .../internal/ConfigSharedPrefsClientTest.java | 7 ++-- .../remoteconfig/ktx/RemoteConfigTests.kt | 2 +- 14 files changed, 75 insertions(+), 67 deletions(-) diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt index 8ec1016ffc9..16447dbc5ad 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,27 +23,27 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigSharedPrefsClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigSharedPrefsClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index aef2419e791..1e1bfae692e 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,8 +32,8 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before diff --git a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java index 3dd8807fe5c..adb5d2f4ea8 100644 --- a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java +++ b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java @@ -35,8 +35,8 @@ import com.google.firebase.remoteconfig.internal.ConfigContainer; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.Date; import java.util.HashMap; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index 500817310c6..ea394551852 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -33,8 +33,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.DefaultsXmlParser; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.ArrayList; @@ -667,11 +667,11 @@ private Task setDefaultsWithStringsMapAsync(Map defaultsSt @NonNull public Task setCustomSignals(@NonNull Map customSignals) { return Tasks.call( - executor, - () -> { - frcMetadata.setCustomSignals(customSignals); - return null; - }); + executor, + () -> { + frcMetadata.setCustomSignals(customSignals); + return null; + }); } /** diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java index 966de92001c..36eb5650541 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java @@ -36,8 +36,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigStorageClient; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateFactory; @@ -268,7 +268,9 @@ ConfigFetchHttpClient getFrcBackendApiClient( @VisibleForTesting synchronized ConfigFetchHandler getFetchHandler( - String namespace, ConfigCacheClient fetchedCacheClient, ConfigSharedPrefsClient metadataClient) { + String namespace, + ConfigCacheClient fetchedCacheClient, + ConfigSharedPrefsClient metadataClient) { return new ConfigFetchHandler( firebaseInstallations, isPrimaryApp(firebaseApp) ? analyticsConnector : () -> null, @@ -306,7 +308,8 @@ private ConfigGetParameterHandler getGetHandler( } @VisibleForTesting - static ConfigSharedPrefsClient getMetadataClient(Context context, String appId, String namespace) { + static ConfigSharedPrefsClient getMetadataClient( + Context context, String appId, String namespace) { String fileName = String.format( "%s_%s_%s_%s", diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java index 70dd1e19398..3b8cf307dd7 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java @@ -308,7 +308,7 @@ private JSONObject createFetchRequestBody( String installationAuthToken, Map analyticsUserProperties, Long firstOpenTime) - throws FirebaseRemoteConfigClientException { + throws FirebaseRemoteConfigClientException { Map requestBodyMap = new HashMap<>(); if (installationId == null) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java index eb796493c0f..29f2f2ad1df 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java @@ -30,16 +30,13 @@ import androidx.annotation.WorkerThread; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; - -import org.json.JSONException; -import org.json.JSONObject; - import java.lang.annotation.Retention; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.Objects; +import org.json.JSONException; +import org.json.JSONObject; /** * Client for handling Firebase Remote Config (FRC) metadata that is saved to disk and persisted @@ -265,17 +262,25 @@ public void setCustomSignals(Map newCustomSignals) { // Retrieve existing custom signals Map existingCustomSignals = getCustomSignals(); - // Merge new signals with existing ones (new signals take precedence) - existingCustomSignals.putAll(newCustomSignals); - - // Ignore key-value pairs with null values, which signify unset signals. - existingCustomSignals.values().removeIf(Objects::isNull); + for (Map.Entry entry : newCustomSignals.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + // Merge new signals with existing ones, overwriting existing keys. + // Also, remove entries where the new value is null. + if (value != null) { + existingCustomSignals.put(key, value); + } else { + existingCustomSignals.remove(key); + } + } frcMetadata - .edit() - .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) - .commit(); + .edit() + .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) + .commit(); } } + public Map getCustomSignals() { String jsonString = frcMetadata.getString(CUSTOM_SIGNALS, "{}"); try { @@ -292,7 +297,6 @@ public Map getCustomSignals() { } } - void resetBackoff() { setBackoffMetadata(NO_FAILED_FETCHES, NO_BACKOFF_TIME); } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 7341f8ea296..187fd79a4a7 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -72,9 +72,9 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHttpClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.FakeHttpURLConnection; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; @@ -350,7 +350,8 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { mockRetryListener, scheduledExecutorService); realtimeMetadataClient = - new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient( + context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); configRealtimeHttpClient = new ConfigRealtimeHttpClient( firebaseApp, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index 450ec30a532..d7646965513 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -29,8 +29,8 @@ import com.google.firebase.platforminfo.UserAgentPublisher import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt index 8ec1016ffc9..16447dbc5ad 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,27 +23,27 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigSharedPrefsClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigSharedPrefsClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java index c383d505c19..3269b18dd6f 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java @@ -143,7 +143,8 @@ public void setUp() throws Exception { context = ApplicationProvider.getApplicationContext(); mockClock = new MockClock(0L); metadataClient = - new ConfigSharedPrefsClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigSharedPrefsClient( + context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); loadBackendApiClient(); loadInstallationIdAndAuthToken(); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java index 32b37820ccf..1a6426482d8 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java @@ -86,10 +86,10 @@ public class ConfigFetchHttpClientTest { "etag-" + PROJECT_NUMBER + "-" + DEFAULT_NAMESPACE + "-fetch-%d"; private static final String FIRST_ETAG = String.format(ETAG_FORMAT, 1); private static final String SECOND_ETAG = String.format(ETAG_FORMAT, 2); - private static final Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + private static final Map SAMPLE_CUSTOM_SIGNALS = + ImmutableMap.of( "subscription", "premium", - "age", "20" - ); + "age", "20"); private Context context; private ConfigFetchHttpClient configFetchHttpClient; @@ -245,7 +245,7 @@ public void fetch_setsAllElementsOfRequestBody_sendsRequestBodyToServer() throws assertThat(requestBody.getJSONObject(ANALYTICS_USER_PROPERTIES).toString()) .isEqualTo(new JSONObject(customUserProperties).toString()); assertThat(requestBody.getJSONObject(CUSTOM_SIGNALS).toString()) - .isEqualTo(new JSONObject(SAMPLE_CUSTOM_SIGNALS).toString()); + .isEqualTo(new JSONObject(SAMPLE_CUSTOM_SIGNALS).toString()); } @Test diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java index 93f2ec7ac74..a78b345c71a 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java @@ -35,7 +35,6 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; - import java.util.Collections; import java.util.Date; import java.util.Map; @@ -361,10 +360,10 @@ public void getCustomSignals_isNotSet_returnsEmptyMap() { @Test public void getCustomSignals_isSet_returnsCustomSignals() { - Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( + Map SAMPLE_CUSTOM_SIGNALS = + ImmutableMap.of( "subscription", "premium", - "age", "20" - ); + "age", "20"); metadataClient.setCustomSignals(SAMPLE_CUSTOM_SIGNALS); assertThat(metadataClient.getCustomSignals()).isEqualTo(SAMPLE_CUSTOM_SIGNALS); } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index ad9daae11a6..30bef10ac47 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,8 +32,8 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before From 60ae034bcb88b942feb58092c2197410f46c4293 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Sat, 26 Oct 2024 00:11:33 +0530 Subject: [PATCH 05/17] update the API definition file to include setCustomSignals --- firebase-config/api.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase-config/api.txt b/firebase-config/api.txt index 61528ec5d11..06c549a8a9d 100644 --- a/firebase-config/api.txt +++ b/firebase-config/api.txt @@ -35,6 +35,7 @@ package com.google.firebase.remoteconfig { method @NonNull public com.google.firebase.remoteconfig.FirebaseRemoteConfigValue getValue(@NonNull String); method @NonNull public com.google.android.gms.tasks.Task reset(); method @NonNull public com.google.android.gms.tasks.Task setConfigSettingsAsync(@NonNull com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings); + method @NonNull public com.google.android.gms.tasks.Task setCustomSignals(@NonNull java.util.Map); method @NonNull public com.google.android.gms.tasks.Task setDefaultsAsync(@NonNull java.util.Map); method @NonNull public com.google.android.gms.tasks.Task setDefaultsAsync(@XmlRes int); field public static final boolean DEFAULT_VALUE_FOR_BOOLEAN = false; From d1cac74b7d664283936827a3cda5f3157c936195 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Tue, 5 Nov 2024 22:11:05 +0530 Subject: [PATCH 06/17] Add limits, input validation, and unit tests for custom signals --- firebase-config/gradle.properties | 2 +- .../internal/ConfigSharedPrefsClient.java | 25 ++++++++++- .../internal/ConfigSharedPrefsClientTest.java | 41 +++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/firebase-config/gradle.properties b/firebase-config/gradle.properties index 86c742a105c..a7c09dd043e 100644 --- a/firebase-config/gradle.properties +++ b/firebase-config/gradle.properties @@ -14,7 +14,7 @@ # limitations under the License. # -version=22.0.1 +version=22.0.2 latestReleasedVersion=22.0.0 android.enableUnitTestBinaryResources=true diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java index 29f2f2ad1df..6872eaee17c 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java @@ -266,6 +266,15 @@ public void setCustomSignals(Map newCustomSignals) { String key = entry.getKey(); Object value = entry.getValue(); + // Validate value type, and key and value length + if (value != null && !(value instanceof String || value instanceof Long)) { + throw new IllegalArgumentException("Custom signal values must be of type String or Long"); + } + if (key.length() > 250 || (value instanceof String && ((String) value).length() > 500)) { + throw new IllegalArgumentException( + "Custom signal keys must be 250 characters or less, and string values must be 500 characters or less."); + } + // Merge new signals with existing ones, overwriting existing keys. // Also, remove entries where the new value is null. if (value != null) { @@ -274,6 +283,16 @@ public void setCustomSignals(Map newCustomSignals) { existingCustomSignals.remove(key); } } + + // Check if the map has actually changed and the size limit + if (existingCustomSignals.equals(getCustomSignals())) { + return; + } + if (existingCustomSignals.size() > 100) { + throw new IllegalArgumentException( + "Too many custom signals provided. The maximum allowed is 100."); + } + frcMetadata .edit() .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) @@ -289,7 +308,11 @@ public Map getCustomSignals() { Iterator keys = existingCustomSignalsJson.keys(); while (keys.hasNext()) { String key = keys.next(); - custom_signals.put(key, existingCustomSignalsJson.get(key)); + Object value = existingCustomSignalsJson.get(key); + if (value instanceof Integer) { + value = existingCustomSignalsJson.getLong(key); + } + custom_signals.put(key, value); } return custom_signals; } catch (JSONException e) { diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java index a78b345c71a..a6150488541 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java @@ -25,6 +25,7 @@ import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import android.content.Context; import android.content.SharedPreferences; @@ -37,6 +38,7 @@ import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.Map; import org.junit.Before; import org.junit.Test; @@ -367,4 +369,43 @@ public void getCustomSignals_isSet_returnsCustomSignals() { metadataClient.setCustomSignals(SAMPLE_CUSTOM_SIGNALS); assertThat(metadataClient.getCustomSignals()).isEqualTo(SAMPLE_CUSTOM_SIGNALS); } + + @Test + public void setCustomSignals_multipleTimes_addsNewSignals() { + Map signals1 = ImmutableMap.of("subscription", "premium"); + Map signals2 = ImmutableMap.of("age", 20L); + metadataClient.setCustomSignals(signals1); + metadataClient.setCustomSignals(signals2); + Map expectedSignals = ImmutableMap.of("subscription", "premium", "age", 20L); + assertThat(metadataClient.getCustomSignals()).isEqualTo(expectedSignals); + } + + @Test + public void setCustomSignals_nullValue_removesSignal() { + Map signals1 = ImmutableMap.of("subscription", "premium", "age", 20L); + metadataClient.setCustomSignals(signals1); + Map signals2 = new HashMap<>(); + signals2.put("age", null); + metadataClient.setCustomSignals(signals2); + Map expectedSignals = ImmutableMap.of("subscription", "premium"); + assertThat(metadataClient.getCustomSignals()).isEqualTo(expectedSignals); + } + + @Test + public void setCustomSignals_invalidInput_throwsException() { + Map invalidSignals1 = new HashMap<>(); + invalidSignals1.put("name", true); + assertThrows( + IllegalArgumentException.class, () -> metadataClient.setCustomSignals(invalidSignals1)); + + Map invalidSignals2 = new HashMap<>(); + invalidSignals2.put("a".repeat(251), "value"); + assertThrows( + IllegalArgumentException.class, () -> metadataClient.setCustomSignals(invalidSignals2)); + + Map invalidSignals3 = new HashMap<>(); + invalidSignals3.put("key", "a".repeat(501)); + assertThrows( + IllegalArgumentException.class, () -> metadataClient.setCustomSignals(invalidSignals3)); + } } From 917a462208f81347930a00430ab64f8c3e811d6d Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Wed, 6 Nov 2024 22:27:25 +0530 Subject: [PATCH 07/17] Rename ConfigMetadataClient to ConfigSharedPrefsClient in a different pull request. --- .../remoteconfig/TestConstructorUtil.kt | 28 +++++++++---------- .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +-- .../FirebaseRemoteConfigIntegrationTest.java | 4 +-- .../remoteconfig/FirebaseRemoteConfig.java | 6 ++-- .../remoteconfig/RemoteConfigComponent.java | 16 +++++------ .../internal/ConfigFetchHandler.java | 12 ++++---- ...sClient.java => ConfigMetadataClient.java} | 4 +-- .../internal/ConfigRealtimeHandler.java | 4 +-- .../internal/ConfigRealtimeHttpClient.java | 6 ++-- .../FirebaseRemoteConfigInfoImpl.java | 2 +- .../FirebaseRemoteConfigTest.java | 8 +++--- .../RemoteConfigComponentTest.java | 8 +++--- .../remoteconfig/RemoteConfigTests.kt | 4 +-- .../remoteconfig/TestConstructorUtil.kt | 28 +++++++++---------- .../internal/ConfigFetchHandlerTest.java | 12 ++++---- ...est.java => ConfigMetadataClientTest.java} | 28 +++++++++---------- .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +-- 17 files changed, 89 insertions(+), 89 deletions(-) rename firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/{ConfigSharedPrefsClient.java => ConfigMetadataClient.java} (99%) rename firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/{ConfigSharedPrefsClientTest.java => ConfigMetadataClientTest.java} (93%) diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt index 16447dbc5ad..3be63e122f6 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -24,26 +24,26 @@ import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigSharedPrefsClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigMetadataClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index 1e1bfae692e..3b51e1640d3 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -33,7 +33,7 @@ import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigSharedPrefsClient::class.java), + frcMetadata = mock(ConfigMetadataClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java index adb5d2f4ea8..5882ce988b8 100644 --- a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java +++ b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java @@ -36,7 +36,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.Date; import java.util.HashMap; @@ -60,7 +60,7 @@ public class FirebaseRemoteConfigIntegrationTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigSharedPrefsClient metadataClient; + @Mock private ConfigMetadataClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionHandler; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index ea394551852..6ebbf8a93a8 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -34,7 +34,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.DefaultsXmlParser; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.ArrayList; @@ -160,7 +160,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { private final ConfigCacheClient defaultConfigsCache; private final ConfigFetchHandler fetchHandler; private final ConfigGetParameterHandler getHandler; - private final ConfigSharedPrefsClient frcMetadata; + private final ConfigMetadataClient frcMetadata; private final FirebaseInstallationsApi firebaseInstallations; private final ConfigRealtimeHandler configRealtimeHandler; private final RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler; @@ -181,7 +181,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { ConfigCacheClient defaultConfigsCache, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigSharedPrefsClient frcMetadata, + ConfigMetadataClient frcMetadata, ConfigRealtimeHandler configRealtimeHandler, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { this.context = context; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java index 36eb5650541..ef417ec52ad 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java @@ -37,7 +37,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigStorageClient; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateFactory; @@ -166,7 +166,7 @@ public synchronized FirebaseRemoteConfig get(String namespace) { ConfigCacheClient fetchedCacheClient = getCacheClient(namespace, FETCH_FILE_NAME); ConfigCacheClient activatedCacheClient = getCacheClient(namespace, ACTIVATE_FILE_NAME); ConfigCacheClient defaultsCacheClient = getCacheClient(namespace, DEFAULTS_FILE_NAME); - ConfigSharedPrefsClient metadataClient = getMetadataClient(context, appId, namespace); + ConfigMetadataClient metadataClient = getMetadataClient(context, appId, namespace); ConfigGetParameterHandler getHandler = getGetHandler(activatedCacheClient, defaultsCacheClient); Personalization personalization = @@ -206,7 +206,7 @@ synchronized FirebaseRemoteConfig get( ConfigCacheClient defaultsClient, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigSharedPrefsClient metadataClient, + ConfigMetadataClient metadataClient, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { if (!frcNamespaceInstances.containsKey(namespace)) { FirebaseRemoteConfig in = @@ -254,7 +254,7 @@ private ConfigCacheClient getCacheClient(String namespace, String configStoreTyp @VisibleForTesting ConfigFetchHttpClient getFrcBackendApiClient( - String apiKey, String namespace, ConfigSharedPrefsClient metadataClient) { + String apiKey, String namespace, ConfigMetadataClient metadataClient) { String appId = firebaseApp.getOptions().getApplicationId(); return new ConfigFetchHttpClient( context, @@ -270,7 +270,7 @@ ConfigFetchHttpClient getFrcBackendApiClient( synchronized ConfigFetchHandler getFetchHandler( String namespace, ConfigCacheClient fetchedCacheClient, - ConfigSharedPrefsClient metadataClient) { + ConfigMetadataClient metadataClient) { return new ConfigFetchHandler( firebaseInstallations, isPrimaryApp(firebaseApp) ? analyticsConnector : () -> null, @@ -290,7 +290,7 @@ synchronized ConfigRealtimeHandler getRealtime( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigSharedPrefsClient metadataClient) { + ConfigMetadataClient metadataClient) { return new ConfigRealtimeHandler( firebaseApp, firebaseInstallations, @@ -308,14 +308,14 @@ private ConfigGetParameterHandler getGetHandler( } @VisibleForTesting - static ConfigSharedPrefsClient getMetadataClient( + static ConfigMetadataClient getMetadataClient( Context context, String appId, String namespace) { String fileName = String.format( "%s_%s_%s_%s", FIREBASE_REMOTE_CONFIG_FILE_NAME_PREFIX, appId, namespace, PREFERENCES_FILE_NAME); SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); - return new ConfigSharedPrefsClient(preferences); + return new ConfigMetadataClient(preferences); } @Nullable diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java index fe0ba19e4bb..7c98589b153 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java @@ -14,7 +14,7 @@ package com.google.firebase.remoteconfig.internal; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT; @@ -43,7 +43,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse.Status; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.HttpURLConnection; @@ -96,7 +96,7 @@ public class ConfigFetchHandler { private final Random randomGenerator; private final ConfigCacheClient fetchedConfigsCache; private final ConfigFetchHttpClient frcBackendApiClient; - private final ConfigSharedPrefsClient frcMetadata; + private final ConfigMetadataClient frcMetadata; private final Map customHttpHeaders; @@ -109,7 +109,7 @@ public ConfigFetchHandler( Random randomGenerator, ConfigCacheClient fetchedConfigsCache, ConfigFetchHttpClient frcBackendApiClient, - ConfigSharedPrefsClient frcMetadata, + ConfigMetadataClient frcMetadata, Map customHttpHeaders) { this.firebaseInstallations = firebaseInstallations; this.analyticsConnector = analyticsConnector; @@ -124,7 +124,7 @@ public ConfigFetchHandler( /** * Calls {@link #fetch(long)} with the {@link - * ConfigSharedPrefsClient#getMinimumFetchIntervalInSeconds()}. + * ConfigMetadataClient#getMinimumFetchIntervalInSeconds()}. */ public Task fetch() { return fetch(frcMetadata.getMinimumFetchIntervalInSeconds()); @@ -228,7 +228,7 @@ public Task fetchNowWithTypeAndAttemptNumber( * currently throttled. * *

If a fetch request is made to the backend, updates the last fetch status, last successful - * fetch time and {@link BackoffMetadata} in {@link ConfigSharedPrefsClient}. + * fetch time and {@link BackoffMetadata} in {@link ConfigMetadataClient}. */ private Task fetchIfCacheExpiredAndNotThrottled( Task cachedFetchConfigsTask, diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java similarity index 99% rename from firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java rename to firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java index 6872eaee17c..6e9a3ca3cb6 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java @@ -44,7 +44,7 @@ * * @author Miraziz Yusupov */ -public class ConfigSharedPrefsClient { +public class ConfigMetadataClient { @Retention(SOURCE) @IntDef({ LAST_FETCH_STATUS_SUCCESS, @@ -88,7 +88,7 @@ public class ConfigSharedPrefsClient { private final Object realtimeBackoffMetadataLock; private final Object customSignalsLock; - public ConfigSharedPrefsClient(SharedPreferences frcMetadata) { + public ConfigMetadataClient(SharedPreferences frcMetadata) { this.frcMetadata = frcMetadata; this.frcInfoLock = new Object(); this.backoffMetadataLock = new Object(); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java index 26dcbc9cce0..53f89a71e8c 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java @@ -39,7 +39,7 @@ public class ConfigRealtimeHandler { private final ConfigCacheClient activatedCacheClient; private final Context context; private final String namespace; - private final ConfigSharedPrefsClient metadataClient; + private final ConfigMetadataClient metadataClient; private final ScheduledExecutorService scheduledExecutorService; public ConfigRealtimeHandler( @@ -49,7 +49,7 @@ public ConfigRealtimeHandler( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigSharedPrefsClient metadataClient, + ConfigMetadataClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = new LinkedHashSet<>(); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java index a2f0a26b8c5..ef0ef2defc5 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java @@ -110,7 +110,7 @@ public class ConfigRealtimeHttpClient { private final String namespace; private final Random random; private final Clock clock; - private final ConfigSharedPrefsClient metadataClient; + private final ConfigMetadataClient metadataClient; public ConfigRealtimeHttpClient( FirebaseApp firebaseApp, @@ -120,7 +120,7 @@ public ConfigRealtimeHttpClient( Context context, String namespace, Set listeners, - ConfigSharedPrefsClient metadataClient, + ConfigMetadataClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = listeners; @@ -473,7 +473,7 @@ public void beginRealtimeHttpStream() { return; } - ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Date currentTime = new Date(clock.currentTimeMillis()); if (currentTime.before(backoffMetadata.getBackoffEndTime())) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java index 4a16f7bf4e9..15f0bb00028 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java @@ -16,7 +16,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; /** * Impl class for FirebaseRemoteConfigInfo. diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 187fd79a4a7..259dee9b27d 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -74,7 +74,7 @@ import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHttpClient; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.FakeHttpURLConnection; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; @@ -155,7 +155,7 @@ public final class FirebaseRemoteConfigTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigSharedPrefsClient metadataClient; + @Mock private ConfigMetadataClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private ConfigAutoFetch mockConfigAutoFetch; @@ -192,7 +192,7 @@ public final class FirebaseRemoteConfigTest { private ConfigContainer realtimeFetchedContainer; private ConfigAutoFetch configAutoFetch; private ConfigRealtimeHttpClient configRealtimeHttpClient; - private ConfigSharedPrefsClient realtimeMetadataClient; + private ConfigMetadataClient realtimeMetadataClient; private FetchResponse firstFetchedContainerResponse; @@ -350,7 +350,7 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { mockRetryListener, scheduledExecutorService); realtimeMetadataClient = - new ConfigSharedPrefsClient( + new ConfigMetadataClient( context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); configRealtimeHttpClient = new ConfigRealtimeHttpClient( diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java index 7511ffe4a63..c6869267a4d 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java @@ -39,7 +39,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import com.google.firebase.remoteconfig.interop.rollouts.RolloutsStateSubscriber; import java.util.Date; @@ -73,7 +73,7 @@ public class RemoteConfigComponentTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetParameterHandler; - @Mock private ConfigSharedPrefsClient mockMetadataClient; + @Mock private ConfigMetadataClient mockMetadataClient; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionsHandler; @Mock private RolloutsStateSubscriber mockRolloutsStateSubscriber; @@ -82,7 +82,7 @@ public class RemoteConfigComponentTest { private ExecutorService directExecutor; private ScheduledExecutorService scheduledExecutorService; private FirebaseApp defaultApp; - private ConfigSharedPrefsClient metadataClient; + private ConfigMetadataClient metadataClient; @Before public void setUp() { @@ -183,7 +183,7 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { public void registerRolloutsStateSubscriber_firebaseNamespace_callsSubscriptionHandler() { // Mock metadata client response since Realtime handler can't be mocked here. when(mockMetadataClient.getRealtimeBackoffMetadata()) - .thenReturn(new ConfigSharedPrefsClient.RealtimeBackoffMetadata(0, new Date())); + .thenReturn(new ConfigMetadataClient.RealtimeBackoffMetadata(0, new Date())); RemoteConfigComponent frcComponent = getNewFrcComponentWithoutLoadingDefault(); FirebaseRemoteConfig instance = getFrcInstanceFromComponent(frcComponent, DEFAULT_NAMESPACE); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index d7646965513..da88e320900 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -30,7 +30,7 @@ import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -139,7 +139,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigSharedPrefsClient::class.java), + frcMetadata = mock(ConfigMetadataClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt index 16447dbc5ad..3be63e122f6 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -24,26 +24,26 @@ import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor // This method is a workaround for testing. It enable us to create a FirebaseRemoteConfig object // with mocks using the package-private constructor. fun createRemoteConfig( - context: Context?, - firebaseApp: FirebaseApp, - firebaseInstallations: FirebaseInstallationsApi, - firebaseAbt: FirebaseABTesting?, - executor: Executor, - fetchedConfigsCache: ConfigCacheClient, - activatedConfigsCache: ConfigCacheClient, - defaultConfigsCache: ConfigCacheClient, - fetchHandler: ConfigFetchHandler, - getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigSharedPrefsClient, - realtimeHandler: ConfigRealtimeHandler, - rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler + context: Context?, + firebaseApp: FirebaseApp, + firebaseInstallations: FirebaseInstallationsApi, + firebaseAbt: FirebaseABTesting?, + executor: Executor, + fetchedConfigsCache: ConfigCacheClient, + activatedConfigsCache: ConfigCacheClient, + defaultConfigsCache: ConfigCacheClient, + fetchHandler: ConfigFetchHandler, + getHandler: ConfigGetParameterHandler, + frcMetadata: ConfigMetadataClient, + realtimeHandler: ConfigRealtimeHandler, + rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { return FirebaseRemoteConfig( context, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java index 3269b18dd6f..605a6bd8751 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java @@ -29,9 +29,9 @@ import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FIRST_OPEN_TIME_KEY; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.HTTP_TOO_MANY_REQUESTS; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; @@ -70,7 +70,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; @@ -127,7 +127,7 @@ public class ConfigFetchHandlerTest { private Context context; @Mock private FirebaseInstallationsApi mockFirebaseInstallations; - private ConfigSharedPrefsClient metadataClient; + private ConfigMetadataClient metadataClient; private ConfigFetchHandler fetchHandler; @@ -143,7 +143,7 @@ public void setUp() throws Exception { context = ApplicationProvider.getApplicationContext(); mockClock = new MockClock(0L); metadataClient = - new ConfigSharedPrefsClient( + new ConfigMetadataClient( context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); loadBackendApiClient(); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java similarity index 93% rename from firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java rename to firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java index a6150488541..3a799ebc3fe 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java @@ -21,10 +21,10 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import android.content.Context; @@ -34,8 +34,8 @@ import com.google.common.collect.ImmutableMap; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -47,14 +47,14 @@ import org.robolectric.annotation.Config; /** - * Unit tests for the {@link ConfigSharedPrefsClient}. + * Unit tests for the {@link ConfigMetadataClient}. * * @author Miraziz Yusupov */ @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class ConfigSharedPrefsClientTest { - private ConfigSharedPrefsClient metadataClient; +public class ConfigMetadataClientTest { + private ConfigMetadataClient metadataClient; private FirebaseRemoteConfigSettings.Builder settingsBuilder; @Before @@ -65,7 +65,7 @@ public void setUp() { metadata.edit().clear().commit(); - metadataClient = new ConfigSharedPrefsClient(metadata); + metadataClient = new ConfigMetadataClient(metadata); settingsBuilder = new FirebaseRemoteConfigSettings.Builder(); } @@ -160,7 +160,7 @@ public void getLastTemplateVersion_isSet_returnsTemplateVersion() { @Test public void getRealtimeBackoffMetadata_isNotSet_returnsNoFailedStreamsAndNotThrottled() { - ConfigSharedPrefsClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(defaultRealtimeBackoffMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); @@ -173,7 +173,7 @@ public void getRealtimeBackoffMetadata_hasValues_returnsValues() { Date backoffEndTime = new Date(1000L); metadataClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); - ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(backoffMetadata.getNumFailedStreams()).isEqualTo(numFailedStreams); @@ -185,7 +185,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.setRealtimeBackoffMetadata( /* numFailedStreams= */ 5, /* backoffEndTime= */ new Date(1000L)); - ConfigSharedPrefsClient.RealtimeBackoffMetadata realtimeBackoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata realtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Preconditions.checkArgument(realtimeBackoffMetadata.getNumFailedStreams() != NO_FAILED_FETCHES); Preconditions.checkArgument( @@ -193,7 +193,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.resetRealtimeBackoff(); - ConfigSharedPrefsClient.RealtimeBackoffMetadata resetMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata resetMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(resetMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); assertThat(resetMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index 30bef10ac47..4e24acba3aa 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -33,7 +33,7 @@ import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigSharedPrefsClient::class.java), + frcMetadata = mock(ConfigMetadataClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) From deb3d847a62fbd784031bb1a5ab889412e7af933 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Wed, 6 Nov 2024 22:27:25 +0530 Subject: [PATCH 08/17] Rename ConfigMetadataClient to ConfigSharedPrefsClient in a different pull request. --- .../remoteconfig/TestConstructorUtil.kt | 4 +-- .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +-- .../FirebaseRemoteConfigIntegrationTest.java | 4 +-- .../remoteconfig/FirebaseRemoteConfig.java | 6 ++-- .../remoteconfig/RemoteConfigComponent.java | 19 ++++++------- .../internal/ConfigFetchHandler.java | 12 ++++---- ...sClient.java => ConfigMetadataClient.java} | 4 +-- .../internal/ConfigRealtimeHandler.java | 4 +-- .../internal/ConfigRealtimeHttpClient.java | 6 ++-- .../FirebaseRemoteConfigInfoImpl.java | 2 +- .../FirebaseRemoteConfigTest.java | 9 +++--- .../RemoteConfigComponentTest.java | 8 +++--- .../remoteconfig/RemoteConfigTests.kt | 4 +-- .../remoteconfig/TestConstructorUtil.kt | 4 +-- .../internal/ConfigFetchHandlerTest.java | 13 ++++----- ...est.java => ConfigMetadataClientTest.java} | 28 +++++++++---------- .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +-- 17 files changed, 65 insertions(+), 70 deletions(-) rename firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/{ConfigSharedPrefsClient.java => ConfigMetadataClient.java} (99%) rename firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/{ConfigSharedPrefsClientTest.java => ConfigMetadataClientTest.java} (93%) diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt index 16447dbc5ad..e6167b5ab09 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,8 +23,8 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -41,7 +41,7 @@ fun createRemoteConfig( defaultConfigsCache: ConfigCacheClient, fetchHandler: ConfigFetchHandler, getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigSharedPrefsClient, + frcMetadata: ConfigMetadataClient, realtimeHandler: ConfigRealtimeHandler, rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index 1e1bfae692e..bb525cf4090 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,8 +32,8 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigSharedPrefsClient::class.java), + frcMetadata = mock(ConfigMetadataClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java index adb5d2f4ea8..19900986b6f 100644 --- a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java +++ b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java @@ -35,8 +35,8 @@ import com.google.firebase.remoteconfig.internal.ConfigContainer; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.Date; import java.util.HashMap; @@ -60,7 +60,7 @@ public class FirebaseRemoteConfigIntegrationTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigSharedPrefsClient metadataClient; + @Mock private ConfigMetadataClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionHandler; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index ea394551852..aecbd2a63de 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -33,8 +33,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.DefaultsXmlParser; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.ArrayList; @@ -160,7 +160,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { private final ConfigCacheClient defaultConfigsCache; private final ConfigFetchHandler fetchHandler; private final ConfigGetParameterHandler getHandler; - private final ConfigSharedPrefsClient frcMetadata; + private final ConfigMetadataClient frcMetadata; private final FirebaseInstallationsApi firebaseInstallations; private final ConfigRealtimeHandler configRealtimeHandler; private final RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler; @@ -181,7 +181,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { ConfigCacheClient defaultConfigsCache, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigSharedPrefsClient frcMetadata, + ConfigMetadataClient frcMetadata, ConfigRealtimeHandler configRealtimeHandler, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { this.context = context; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java index 36eb5650541..e1e02d5f043 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java @@ -36,8 +36,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigStorageClient; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateFactory; @@ -166,7 +166,7 @@ public synchronized FirebaseRemoteConfig get(String namespace) { ConfigCacheClient fetchedCacheClient = getCacheClient(namespace, FETCH_FILE_NAME); ConfigCacheClient activatedCacheClient = getCacheClient(namespace, ACTIVATE_FILE_NAME); ConfigCacheClient defaultsCacheClient = getCacheClient(namespace, DEFAULTS_FILE_NAME); - ConfigSharedPrefsClient metadataClient = getMetadataClient(context, appId, namespace); + ConfigMetadataClient metadataClient = getMetadataClient(context, appId, namespace); ConfigGetParameterHandler getHandler = getGetHandler(activatedCacheClient, defaultsCacheClient); Personalization personalization = @@ -206,7 +206,7 @@ synchronized FirebaseRemoteConfig get( ConfigCacheClient defaultsClient, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigSharedPrefsClient metadataClient, + ConfigMetadataClient metadataClient, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { if (!frcNamespaceInstances.containsKey(namespace)) { FirebaseRemoteConfig in = @@ -254,7 +254,7 @@ private ConfigCacheClient getCacheClient(String namespace, String configStoreTyp @VisibleForTesting ConfigFetchHttpClient getFrcBackendApiClient( - String apiKey, String namespace, ConfigSharedPrefsClient metadataClient) { + String apiKey, String namespace, ConfigMetadataClient metadataClient) { String appId = firebaseApp.getOptions().getApplicationId(); return new ConfigFetchHttpClient( context, @@ -268,9 +268,7 @@ ConfigFetchHttpClient getFrcBackendApiClient( @VisibleForTesting synchronized ConfigFetchHandler getFetchHandler( - String namespace, - ConfigCacheClient fetchedCacheClient, - ConfigSharedPrefsClient metadataClient) { + String namespace, ConfigCacheClient fetchedCacheClient, ConfigMetadataClient metadataClient) { return new ConfigFetchHandler( firebaseInstallations, isPrimaryApp(firebaseApp) ? analyticsConnector : () -> null, @@ -290,7 +288,7 @@ synchronized ConfigRealtimeHandler getRealtime( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigSharedPrefsClient metadataClient) { + ConfigMetadataClient metadataClient) { return new ConfigRealtimeHandler( firebaseApp, firebaseInstallations, @@ -308,14 +306,13 @@ private ConfigGetParameterHandler getGetHandler( } @VisibleForTesting - static ConfigSharedPrefsClient getMetadataClient( - Context context, String appId, String namespace) { + static ConfigMetadataClient getMetadataClient(Context context, String appId, String namespace) { String fileName = String.format( "%s_%s_%s_%s", FIREBASE_REMOTE_CONFIG_FILE_NAME_PREFIX, appId, namespace, PREFERENCES_FILE_NAME); SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); - return new ConfigSharedPrefsClient(preferences); + return new ConfigMetadataClient(preferences); } @Nullable diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java index fe0ba19e4bb..7c98589b153 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java @@ -14,7 +14,7 @@ package com.google.firebase.remoteconfig.internal; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT; @@ -43,7 +43,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse.Status; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.HttpURLConnection; @@ -96,7 +96,7 @@ public class ConfigFetchHandler { private final Random randomGenerator; private final ConfigCacheClient fetchedConfigsCache; private final ConfigFetchHttpClient frcBackendApiClient; - private final ConfigSharedPrefsClient frcMetadata; + private final ConfigMetadataClient frcMetadata; private final Map customHttpHeaders; @@ -109,7 +109,7 @@ public ConfigFetchHandler( Random randomGenerator, ConfigCacheClient fetchedConfigsCache, ConfigFetchHttpClient frcBackendApiClient, - ConfigSharedPrefsClient frcMetadata, + ConfigMetadataClient frcMetadata, Map customHttpHeaders) { this.firebaseInstallations = firebaseInstallations; this.analyticsConnector = analyticsConnector; @@ -124,7 +124,7 @@ public ConfigFetchHandler( /** * Calls {@link #fetch(long)} with the {@link - * ConfigSharedPrefsClient#getMinimumFetchIntervalInSeconds()}. + * ConfigMetadataClient#getMinimumFetchIntervalInSeconds()}. */ public Task fetch() { return fetch(frcMetadata.getMinimumFetchIntervalInSeconds()); @@ -228,7 +228,7 @@ public Task fetchNowWithTypeAndAttemptNumber( * currently throttled. * *

If a fetch request is made to the backend, updates the last fetch status, last successful - * fetch time and {@link BackoffMetadata} in {@link ConfigSharedPrefsClient}. + * fetch time and {@link BackoffMetadata} in {@link ConfigMetadataClient}. */ private Task fetchIfCacheExpiredAndNotThrottled( Task cachedFetchConfigsTask, diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java similarity index 99% rename from firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java rename to firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java index 6872eaee17c..6e9a3ca3cb6 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java @@ -44,7 +44,7 @@ * * @author Miraziz Yusupov */ -public class ConfigSharedPrefsClient { +public class ConfigMetadataClient { @Retention(SOURCE) @IntDef({ LAST_FETCH_STATUS_SUCCESS, @@ -88,7 +88,7 @@ public class ConfigSharedPrefsClient { private final Object realtimeBackoffMetadataLock; private final Object customSignalsLock; - public ConfigSharedPrefsClient(SharedPreferences frcMetadata) { + public ConfigMetadataClient(SharedPreferences frcMetadata) { this.frcMetadata = frcMetadata; this.frcInfoLock = new Object(); this.backoffMetadataLock = new Object(); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java index 26dcbc9cce0..53f89a71e8c 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java @@ -39,7 +39,7 @@ public class ConfigRealtimeHandler { private final ConfigCacheClient activatedCacheClient; private final Context context; private final String namespace; - private final ConfigSharedPrefsClient metadataClient; + private final ConfigMetadataClient metadataClient; private final ScheduledExecutorService scheduledExecutorService; public ConfigRealtimeHandler( @@ -49,7 +49,7 @@ public ConfigRealtimeHandler( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigSharedPrefsClient metadataClient, + ConfigMetadataClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = new LinkedHashSet<>(); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java index a2f0a26b8c5..ef0ef2defc5 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java @@ -110,7 +110,7 @@ public class ConfigRealtimeHttpClient { private final String namespace; private final Random random; private final Clock clock; - private final ConfigSharedPrefsClient metadataClient; + private final ConfigMetadataClient metadataClient; public ConfigRealtimeHttpClient( FirebaseApp firebaseApp, @@ -120,7 +120,7 @@ public ConfigRealtimeHttpClient( Context context, String namespace, Set listeners, - ConfigSharedPrefsClient metadataClient, + ConfigMetadataClient metadataClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = listeners; @@ -473,7 +473,7 @@ public void beginRealtimeHttpStream() { return; } - ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Date currentTime = new Date(clock.currentTimeMillis()); if (currentTime.before(backoffMetadata.getBackoffEndTime())) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java index 4a16f7bf4e9..15f0bb00028 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java @@ -16,7 +16,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; /** * Impl class for FirebaseRemoteConfigInfo. diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 187fd79a4a7..81f292a4c2b 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -72,9 +72,9 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHttpClient; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.FakeHttpURLConnection; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; @@ -155,7 +155,7 @@ public final class FirebaseRemoteConfigTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigSharedPrefsClient metadataClient; + @Mock private ConfigMetadataClient metadataClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private ConfigAutoFetch mockConfigAutoFetch; @@ -192,7 +192,7 @@ public final class FirebaseRemoteConfigTest { private ConfigContainer realtimeFetchedContainer; private ConfigAutoFetch configAutoFetch; private ConfigRealtimeHttpClient configRealtimeHttpClient; - private ConfigSharedPrefsClient realtimeMetadataClient; + private ConfigMetadataClient realtimeMetadataClient; private FetchResponse firstFetchedContainerResponse; @@ -350,8 +350,7 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { mockRetryListener, scheduledExecutorService); realtimeMetadataClient = - new ConfigSharedPrefsClient( - context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); configRealtimeHttpClient = new ConfigRealtimeHttpClient( firebaseApp, diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java index 7511ffe4a63..c6869267a4d 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java @@ -39,7 +39,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import com.google.firebase.remoteconfig.interop.rollouts.RolloutsStateSubscriber; import java.util.Date; @@ -73,7 +73,7 @@ public class RemoteConfigComponentTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetParameterHandler; - @Mock private ConfigSharedPrefsClient mockMetadataClient; + @Mock private ConfigMetadataClient mockMetadataClient; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionsHandler; @Mock private RolloutsStateSubscriber mockRolloutsStateSubscriber; @@ -82,7 +82,7 @@ public class RemoteConfigComponentTest { private ExecutorService directExecutor; private ScheduledExecutorService scheduledExecutorService; private FirebaseApp defaultApp; - private ConfigSharedPrefsClient metadataClient; + private ConfigMetadataClient metadataClient; @Before public void setUp() { @@ -183,7 +183,7 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { public void registerRolloutsStateSubscriber_firebaseNamespace_callsSubscriptionHandler() { // Mock metadata client response since Realtime handler can't be mocked here. when(mockMetadataClient.getRealtimeBackoffMetadata()) - .thenReturn(new ConfigSharedPrefsClient.RealtimeBackoffMetadata(0, new Date())); + .thenReturn(new ConfigMetadataClient.RealtimeBackoffMetadata(0, new Date())); RemoteConfigComponent frcComponent = getNewFrcComponentWithoutLoadingDefault(); FirebaseRemoteConfig instance = getFrcInstanceFromComponent(frcComponent, DEFAULT_NAMESPACE); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index d7646965513..7624ee3827d 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -29,8 +29,8 @@ import com.google.firebase.platforminfo.UserAgentPublisher import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -139,7 +139,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigSharedPrefsClient::class.java), + frcMetadata = mock(ConfigMetadataClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt index 16447dbc5ad..e6167b5ab09 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,8 +23,8 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -41,7 +41,7 @@ fun createRemoteConfig( defaultConfigsCache: ConfigCacheClient, fetchHandler: ConfigFetchHandler, getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigSharedPrefsClient, + frcMetadata: ConfigMetadataClient, realtimeHandler: ConfigRealtimeHandler, rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java index 3269b18dd6f..ed2781710fd 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java @@ -29,9 +29,9 @@ import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FIRST_OPEN_TIME_KEY; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.HTTP_TOO_MANY_REQUESTS; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; @@ -70,7 +70,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; @@ -127,7 +127,7 @@ public class ConfigFetchHandlerTest { private Context context; @Mock private FirebaseInstallationsApi mockFirebaseInstallations; - private ConfigSharedPrefsClient metadataClient; + private ConfigMetadataClient metadataClient; private ConfigFetchHandler fetchHandler; @@ -143,8 +143,7 @@ public void setUp() throws Exception { context = ApplicationProvider.getApplicationContext(); mockClock = new MockClock(0L); metadataClient = - new ConfigSharedPrefsClient( - context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); loadBackendApiClient(); loadInstallationIdAndAuthToken(); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java similarity index 93% rename from firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java rename to firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java index a6150488541..3a799ebc3fe 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java @@ -21,10 +21,10 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import android.content.Context; @@ -34,8 +34,8 @@ import com.google.common.collect.ImmutableMap; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -47,14 +47,14 @@ import org.robolectric.annotation.Config; /** - * Unit tests for the {@link ConfigSharedPrefsClient}. + * Unit tests for the {@link ConfigMetadataClient}. * * @author Miraziz Yusupov */ @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class ConfigSharedPrefsClientTest { - private ConfigSharedPrefsClient metadataClient; +public class ConfigMetadataClientTest { + private ConfigMetadataClient metadataClient; private FirebaseRemoteConfigSettings.Builder settingsBuilder; @Before @@ -65,7 +65,7 @@ public void setUp() { metadata.edit().clear().commit(); - metadataClient = new ConfigSharedPrefsClient(metadata); + metadataClient = new ConfigMetadataClient(metadata); settingsBuilder = new FirebaseRemoteConfigSettings.Builder(); } @@ -160,7 +160,7 @@ public void getLastTemplateVersion_isSet_returnsTemplateVersion() { @Test public void getRealtimeBackoffMetadata_isNotSet_returnsNoFailedStreamsAndNotThrottled() { - ConfigSharedPrefsClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(defaultRealtimeBackoffMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); @@ -173,7 +173,7 @@ public void getRealtimeBackoffMetadata_hasValues_returnsValues() { Date backoffEndTime = new Date(1000L); metadataClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); - ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(backoffMetadata.getNumFailedStreams()).isEqualTo(numFailedStreams); @@ -185,7 +185,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.setRealtimeBackoffMetadata( /* numFailedStreams= */ 5, /* backoffEndTime= */ new Date(1000L)); - ConfigSharedPrefsClient.RealtimeBackoffMetadata realtimeBackoffMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata realtimeBackoffMetadata = metadataClient.getRealtimeBackoffMetadata(); Preconditions.checkArgument(realtimeBackoffMetadata.getNumFailedStreams() != NO_FAILED_FETCHES); Preconditions.checkArgument( @@ -193,7 +193,7 @@ public void resetRealtimeBackoff_hasValues_clearsAllValues() { metadataClient.resetRealtimeBackoff(); - ConfigSharedPrefsClient.RealtimeBackoffMetadata resetMetadata = + ConfigMetadataClient.RealtimeBackoffMetadata resetMetadata = metadataClient.getRealtimeBackoffMetadata(); assertThat(resetMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); assertThat(resetMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index 30bef10ac47..c11ea869fbf 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,8 +32,8 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler +import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler -import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigSharedPrefsClient::class.java), + frcMetadata = mock(ConfigMetadataClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) From 92814b7d380e50dfa3dce045d3291ffae1e24f0e Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Mon, 18 Nov 2024 14:09:34 +0530 Subject: [PATCH 09/17] Log warnings for invalid custom signals. --- .../internal/ConfigFetchHttpClient.java | 8 ++++- .../internal/ConfigMetadataClient.java | 33 +++++++++++++++---- .../internal/ConfigMetadataClientTest.java | 29 ++++++++-------- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java index 3b8cf307dd7..67446c0f2b9 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java @@ -351,7 +351,13 @@ private JSONObject createFetchRequestBody( requestBodyMap.put(ANALYTICS_USER_PROPERTIES, new JSONObject(analyticsUserProperties)); - requestBodyMap.put(CUSTOM_SIGNALS, new JSONObject(customSignalMap)); + if (!customSignalMap.isEmpty()) { + Map customSignalsStringMap = new HashMap<>(); + for (Map.Entry entry : customSignalMap.entrySet()) { + customSignalsStringMap.put(entry.getKey(), String.valueOf(entry.getValue())); + } + requestBodyMap.put(CUSTOM_SIGNALS, new JSONObject(customSignalsStringMap)); + } if (firstOpenTime != null) { requestBodyMap.put(FIRST_OPEN_TIME, convertToISOString(firstOpenTime)); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java index 6e9a3ca3cb6..a1073f2f3f1 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java @@ -18,12 +18,14 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_NO_FETCH_YET; import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_SUCCESS; import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; +import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.TAG; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; import static com.google.firebase.remoteconfig.RemoteConfigConstants.RequestFieldKey.CUSTOM_SIGNALS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.content.SharedPreferences; +import android.util.Log; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -81,6 +83,12 @@ public class ConfigMetadataClient { private static final String REALTIME_BACKOFF_END_TIME_IN_MILLIS_KEY = "realtime_backoff_end_time_in_millis"; + /** Constants for custom signal limits. */ + private static final int CUSTOM_SIGNALS_MAX_KEY_LENGTH = 250; + + private static final int CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH = 500; + private static final int CUSTOM_SIGNALS_MAX_COUNT = 100; + private final SharedPreferences frcMetadata; private final Object frcInfoLock; @@ -268,11 +276,18 @@ public void setCustomSignals(Map newCustomSignals) { // Validate value type, and key and value length if (value != null && !(value instanceof String || value instanceof Long)) { - throw new IllegalArgumentException("Custom signal values must be of type String or Long"); + Log.w(TAG, "Invalid custom signal: Custom signal values must be of type String or Long."); + return; } - if (key.length() > 250 || (value instanceof String && ((String) value).length() > 500)) { - throw new IllegalArgumentException( - "Custom signal keys must be 250 characters or less, and string values must be 500 characters or less."); + if (key.length() > CUSTOM_SIGNALS_MAX_KEY_LENGTH + || (value instanceof String + && ((String) value).length() > CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH)) { + Log.w( + TAG, + String.format( + "Invalid custom signal: Custom signal keys must be %d characters or less, and string values must be %d characters or less.", + CUSTOM_SIGNALS_MAX_KEY_LENGTH, CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH)); + return; } // Merge new signals with existing ones, overwriting existing keys. @@ -288,9 +303,13 @@ public void setCustomSignals(Map newCustomSignals) { if (existingCustomSignals.equals(getCustomSignals())) { return; } - if (existingCustomSignals.size() > 100) { - throw new IllegalArgumentException( - "Too many custom signals provided. The maximum allowed is 100."); + if (existingCustomSignals.size() > CUSTOM_SIGNALS_MAX_COUNT) { + Log.w( + TAG, + String.format( + "Invalid custom signal: Too many custom signals provided. The maximum allowed is %d.", + CUSTOM_SIGNALS_MAX_COUNT)); + return; } frcMetadata diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java index 3a799ebc3fe..9d8054d7689 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java @@ -25,7 +25,7 @@ import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; -import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; +import static com.google.firebase.remoteconfig.testutil.Assert.assertFalse; import android.content.Context; import android.content.SharedPreferences; @@ -392,20 +392,17 @@ public void setCustomSignals_nullValue_removesSignal() { } @Test - public void setCustomSignals_invalidInput_throwsException() { - Map invalidSignals1 = new HashMap<>(); - invalidSignals1.put("name", true); - assertThrows( - IllegalArgumentException.class, () -> metadataClient.setCustomSignals(invalidSignals1)); - - Map invalidSignals2 = new HashMap<>(); - invalidSignals2.put("a".repeat(251), "value"); - assertThrows( - IllegalArgumentException.class, () -> metadataClient.setCustomSignals(invalidSignals2)); - - Map invalidSignals3 = new HashMap<>(); - invalidSignals3.put("key", "a".repeat(501)); - assertThrows( - IllegalArgumentException.class, () -> metadataClient.setCustomSignals(invalidSignals3)); + public void setCustomSignals_invalidInput_rejectsSignals() { + Map invalidSignals1 = ImmutableMap.of("name", true); + metadataClient.setCustomSignals(invalidSignals1); + assertFalse(metadataClient.getCustomSignals().containsKey("name")); + + Map invalidSignals2 = ImmutableMap.of("a".repeat(251), "value"); + metadataClient.setCustomSignals(invalidSignals2); + assertFalse(metadataClient.getCustomSignals().containsKey("a".repeat(251))); + + Map invalidSignals3 = ImmutableMap.of("key", "a".repeat(501)); + metadataClient.setCustomSignals(invalidSignals3); + assertFalse(metadataClient.getCustomSignals().containsKey("key")); } } From 288dcd1a5a88b30e96cb5abd0ec49150ff7d4bf9 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Fri, 22 Nov 2024 04:10:34 +0530 Subject: [PATCH 10/17] Add CustomSignals type for restricted values in setCustomSignals. --- firebase-config/api.txt | 12 +++- .../firebase/remoteconfig/CustomSignals.java | 62 +++++++++++++++++++ .../remoteconfig/FirebaseRemoteConfig.java | 15 ++--- .../internal/ConfigFetchHttpClient.java | 14 ++--- .../internal/ConfigMetadataClient.java | 28 +++------ .../internal/ConfigFetchHttpClientTest.java | 2 +- .../internal/ConfigMetadataClientTest.java | 28 ++------- 7 files changed, 101 insertions(+), 60 deletions(-) create mode 100644 firebase-config/src/main/java/com/google/firebase/remoteconfig/CustomSignals.java diff --git a/firebase-config/api.txt b/firebase-config/api.txt index 06c549a8a9d..8afb3042ad4 100644 --- a/firebase-config/api.txt +++ b/firebase-config/api.txt @@ -16,6 +16,16 @@ package com.google.firebase.remoteconfig { method public void remove(); } + public class CustomSignals { + } + + public static class CustomSignals.Builder { + ctor public CustomSignals.Builder(); + method @NonNull public com.google.firebase.remoteconfig.CustomSignals build(); + method @NonNull public com.google.firebase.remoteconfig.CustomSignals.Builder put(@NonNull String, @Nullable String); + method @NonNull public com.google.firebase.remoteconfig.CustomSignals.Builder put(@NonNull String, long); + } + public class FirebaseRemoteConfig { method @NonNull public com.google.android.gms.tasks.Task activate(); method @NonNull public com.google.firebase.remoteconfig.ConfigUpdateListenerRegistration addOnConfigUpdateListener(@NonNull com.google.firebase.remoteconfig.ConfigUpdateListener); @@ -35,7 +45,7 @@ package com.google.firebase.remoteconfig { method @NonNull public com.google.firebase.remoteconfig.FirebaseRemoteConfigValue getValue(@NonNull String); method @NonNull public com.google.android.gms.tasks.Task reset(); method @NonNull public com.google.android.gms.tasks.Task setConfigSettingsAsync(@NonNull com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings); - method @NonNull public com.google.android.gms.tasks.Task setCustomSignals(@NonNull java.util.Map); + method @NonNull public com.google.android.gms.tasks.Task setCustomSignals(@NonNull com.google.firebase.remoteconfig.CustomSignals); method @NonNull public com.google.android.gms.tasks.Task setDefaultsAsync(@NonNull java.util.Map); method @NonNull public com.google.android.gms.tasks.Task setDefaultsAsync(@XmlRes int); field public static final boolean DEFAULT_VALUE_FOR_BOOLEAN = false; diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/CustomSignals.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/CustomSignals.java new file mode 100644 index 00000000000..3701138f9e4 --- /dev/null +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/CustomSignals.java @@ -0,0 +1,62 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.firebase.remoteconfig; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + +/** + * Helper class which handles the storage and conversion to strings of key/value pairs with + * heterogeneous value types for custom signals. + */ +public class CustomSignals { + + final Map customSignals; + + public static class Builder { + // Holds the converted pairs of custom keys and values. + private Map customSignals = new HashMap(); + + // Methods to accept keys and values and convert values to strings. + @NonNull + public Builder put(@NonNull String key, @Nullable String value) { + customSignals.put(key, value); + return this; + } + + @NonNull + public Builder put(@NonNull String key, long value) { + customSignals.put(key, Long.toString(value)); + return this; + } + + @NonNull + public Builder put(@NonNull String key, double value) { + customSignals.put(key, Double.toString(value)); + return this; + } + + @NonNull + public CustomSignals build() { + return new CustomSignals(this); + } + } + + CustomSignals(@NonNull Builder builder) { + this.customSignals = builder.customSignals; + } +} diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index aecbd2a63de..ba8f61af7f4 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -655,21 +655,18 @@ private Task setDefaultsWithStringsMapAsync(Map defaultsSt /** * Asynchronously changes the custom signals for this {@link FirebaseRemoteConfig} instance. * - *

The values in {@code customSignals} must be one of the following types: + *

The {@code customSignals} parameter should be an instance of {@link CustomSignals}, which + * enforces the allowed types for custom signal values (String, Long or Double). * - *

    - *
  • Long - *
  • String - *
- * - * @param customSignals Map (key, value) of the custom signals to be set for the app instance + * @param customSignalsMap A dictionary of keys and the values of the custom signals to be set for + * the app instance */ @NonNull - public Task setCustomSignals(@NonNull Map customSignals) { + public Task setCustomSignals(@NonNull CustomSignals customSignalsMap) { return Tasks.call( executor, () -> { - frcMetadata.setCustomSignals(customSignals); + frcMetadata.setCustomSignals(customSignalsMap.customSignals); return null; }); } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java index 67446c0f2b9..c0a453cfe79 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java @@ -94,7 +94,7 @@ public class ConfigFetchHttpClient { private final String apiKey; private final String projectNumber; private final String namespace; - Map customSignalMap; + Map customSignalsMap; private final long connectTimeoutInSeconds; private final long readTimeoutInSeconds; @@ -109,7 +109,7 @@ public ConfigFetchHttpClient( String namespace, long connectTimeoutInSeconds, long readTimeoutInSeconds, - Map customSignalMap) { + Map customSignalsMap) { this.context = context; this.appId = appId; this.apiKey = apiKey; @@ -117,7 +117,7 @@ public ConfigFetchHttpClient( this.namespace = namespace; this.connectTimeoutInSeconds = connectTimeoutInSeconds; this.readTimeoutInSeconds = readTimeoutInSeconds; - this.customSignalMap = customSignalMap; + this.customSignalsMap = customSignalsMap; } /** Used to verify that the timeout is being set correctly. */ @@ -351,12 +351,8 @@ private JSONObject createFetchRequestBody( requestBodyMap.put(ANALYTICS_USER_PROPERTIES, new JSONObject(analyticsUserProperties)); - if (!customSignalMap.isEmpty()) { - Map customSignalsStringMap = new HashMap<>(); - for (Map.Entry entry : customSignalMap.entrySet()) { - customSignalsStringMap.put(entry.getKey(), String.valueOf(entry.getValue())); - } - requestBodyMap.put(CUSTOM_SIGNALS, new JSONObject(customSignalsStringMap)); + if (!customSignalsMap.isEmpty()) { + requestBodyMap.put(CUSTOM_SIGNALS, new JSONObject(customSignalsMap)); } if (firstOpenTime != null) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java index a1073f2f3f1..dc3db959598 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java @@ -265,27 +265,22 @@ void setBackoffMetadata(int numFailedFetches, Date backoffEndTime) { } } - public void setCustomSignals(Map newCustomSignals) { + public void setCustomSignals(Map newCustomSignals) { synchronized (customSignalsLock) { // Retrieve existing custom signals - Map existingCustomSignals = getCustomSignals(); + Map existingCustomSignals = getCustomSignals(); - for (Map.Entry entry : newCustomSignals.entrySet()) { + for (Map.Entry entry : newCustomSignals.entrySet()) { String key = entry.getKey(); - Object value = entry.getValue(); + String value = entry.getValue(); - // Validate value type, and key and value length - if (value != null && !(value instanceof String || value instanceof Long)) { - Log.w(TAG, "Invalid custom signal: Custom signal values must be of type String or Long."); - return; - } + // Validate key and value length if (key.length() > CUSTOM_SIGNALS_MAX_KEY_LENGTH - || (value instanceof String - && ((String) value).length() > CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH)) { + || (value != null && value.length() > CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH)) { Log.w( TAG, String.format( - "Invalid custom signal: Custom signal keys must be %d characters or less, and string values must be %d characters or less.", + "Invalid custom signal: Custom signal keys must be %d characters or less, and values must be %d characters or less.", CUSTOM_SIGNALS_MAX_KEY_LENGTH, CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH)); return; } @@ -319,18 +314,15 @@ public void setCustomSignals(Map newCustomSignals) { } } - public Map getCustomSignals() { + public Map getCustomSignals() { String jsonString = frcMetadata.getString(CUSTOM_SIGNALS, "{}"); try { JSONObject existingCustomSignalsJson = new JSONObject(jsonString); - Map custom_signals = new HashMap<>(); + Map custom_signals = new HashMap<>(); Iterator keys = existingCustomSignalsJson.keys(); while (keys.hasNext()) { String key = keys.next(); - Object value = existingCustomSignalsJson.get(key); - if (value instanceof Integer) { - value = existingCustomSignalsJson.getLong(key); - } + String value = existingCustomSignalsJson.optString(key); custom_signals.put(key, value); } return custom_signals; diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java index 1a6426482d8..3b658a2dcbe 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClientTest.java @@ -86,7 +86,7 @@ public class ConfigFetchHttpClientTest { "etag-" + PROJECT_NUMBER + "-" + DEFAULT_NAMESPACE + "-fetch-%d"; private static final String FIRST_ETAG = String.format(ETAG_FORMAT, 1); private static final String SECOND_ETAG = String.format(ETAG_FORMAT, 2); - private static final Map SAMPLE_CUSTOM_SIGNALS = + private static final Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( "subscription", "premium", "age", "20"); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java index 9d8054d7689..abbec094298 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java @@ -25,7 +25,6 @@ import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; -import static com.google.firebase.remoteconfig.testutil.Assert.assertFalse; import android.content.Context; import android.content.SharedPreferences; @@ -362,7 +361,7 @@ public void getCustomSignals_isNotSet_returnsEmptyMap() { @Test public void getCustomSignals_isSet_returnsCustomSignals() { - Map SAMPLE_CUSTOM_SIGNALS = + Map SAMPLE_CUSTOM_SIGNALS = ImmutableMap.of( "subscription", "premium", "age", "20"); @@ -372,37 +371,22 @@ public void getCustomSignals_isSet_returnsCustomSignals() { @Test public void setCustomSignals_multipleTimes_addsNewSignals() { - Map signals1 = ImmutableMap.of("subscription", "premium"); - Map signals2 = ImmutableMap.of("age", 20L); + Map signals1 = ImmutableMap.of("subscription", "premium"); + Map signals2 = ImmutableMap.of("age", "20"); metadataClient.setCustomSignals(signals1); metadataClient.setCustomSignals(signals2); - Map expectedSignals = ImmutableMap.of("subscription", "premium", "age", 20L); + Map expectedSignals = ImmutableMap.of("subscription", "premium", "age", "20"); assertThat(metadataClient.getCustomSignals()).isEqualTo(expectedSignals); } @Test public void setCustomSignals_nullValue_removesSignal() { - Map signals1 = ImmutableMap.of("subscription", "premium", "age", 20L); + Map signals1 = ImmutableMap.of("subscription", "premium", "age", "20"); metadataClient.setCustomSignals(signals1); - Map signals2 = new HashMap<>(); + Map signals2 = new HashMap<>(); signals2.put("age", null); metadataClient.setCustomSignals(signals2); Map expectedSignals = ImmutableMap.of("subscription", "premium"); assertThat(metadataClient.getCustomSignals()).isEqualTo(expectedSignals); } - - @Test - public void setCustomSignals_invalidInput_rejectsSignals() { - Map invalidSignals1 = ImmutableMap.of("name", true); - metadataClient.setCustomSignals(invalidSignals1); - assertFalse(metadataClient.getCustomSignals().containsKey("name")); - - Map invalidSignals2 = ImmutableMap.of("a".repeat(251), "value"); - metadataClient.setCustomSignals(invalidSignals2); - assertFalse(metadataClient.getCustomSignals().containsKey("a".repeat(251))); - - Map invalidSignals3 = ImmutableMap.of("key", "a".repeat(501)); - metadataClient.setCustomSignals(invalidSignals3); - assertFalse(metadataClient.getCustomSignals().containsKey("key")); - } } From 88f268f19efab59f0624cd680f53935f6c47a6e5 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Fri, 22 Nov 2024 04:47:52 +0530 Subject: [PATCH 11/17] Add put(String, double) to the CustomSignals.Builder API definition --- firebase-config/api.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase-config/api.txt b/firebase-config/api.txt index 8afb3042ad4..07145facb20 100644 --- a/firebase-config/api.txt +++ b/firebase-config/api.txt @@ -24,6 +24,7 @@ package com.google.firebase.remoteconfig { method @NonNull public com.google.firebase.remoteconfig.CustomSignals build(); method @NonNull public com.google.firebase.remoteconfig.CustomSignals.Builder put(@NonNull String, @Nullable String); method @NonNull public com.google.firebase.remoteconfig.CustomSignals.Builder put(@NonNull String, long); + method @NonNull public com.google.firebase.remoteconfig.CustomSignals.Builder put(@NonNull String, double); } public class FirebaseRemoteConfig { From ccd4b2e66d622fd7df306efc01787c4058e32311 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Fri, 22 Nov 2024 13:32:26 +0530 Subject: [PATCH 12/17] Fix Formating --- .../firebase/remoteconfig/internal/ConfigMetadataClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java index dc3db959598..5f9b01d8202 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java @@ -85,7 +85,6 @@ public class ConfigMetadataClient { /** Constants for custom signal limits. */ private static final int CUSTOM_SIGNALS_MAX_KEY_LENGTH = 250; - private static final int CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH = 500; private static final int CUSTOM_SIGNALS_MAX_COUNT = 100; From 5a15867282b162c8ed449456dd96c40516fbc537 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Fri, 22 Nov 2024 15:06:56 +0530 Subject: [PATCH 13/17] Fix Formating for custom signal limits --- .../firebase/remoteconfig/internal/ConfigMetadataClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java index 5f9b01d8202..c00dbb069bc 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java @@ -83,9 +83,11 @@ public class ConfigMetadataClient { private static final String REALTIME_BACKOFF_END_TIME_IN_MILLIS_KEY = "realtime_backoff_end_time_in_millis"; - /** Constants for custom signal limits. */ + /** Constants for custom signal limits.*/ private static final int CUSTOM_SIGNALS_MAX_KEY_LENGTH = 250; + private static final int CUSTOM_SIGNALS_MAX_STRING_VALUE_LENGTH = 500; + private static final int CUSTOM_SIGNALS_MAX_COUNT = 100; private final SharedPreferences frcMetadata; From 21a39c575b3f1fcd1b955b0e98355f131a0e93f7 Mon Sep 17 00:00:00 2001 From: Tushar Khandelwal <64364243+tusharkhandelwal8@users.noreply.github.com> Date: Sat, 23 Nov 2024 10:52:59 +0530 Subject: [PATCH 14/17] Rename ConfigMetadataClient to ConfigSharedPrefsClient (#6440) Rename ConfigMetadataClient to ConfigSharedPrefsClient Reflects expanded functionality to store both metadata and custom signals in shared preferences. --- .../remoteconfig/TestConstructorUtil.kt | 6 +- .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +- .../FirebaseRemoteConfigIntegrationTest.java | 6 +- .../remoteconfig/FirebaseRemoteConfig.java | 24 +-- .../remoteconfig/RemoteConfigComponent.java | 39 +++-- .../internal/ConfigFetchHandler.java | 43 ++--- .../internal/ConfigRealtimeHandler.java | 8 +- .../internal/ConfigRealtimeHttpClient.java | 24 +-- ...ient.java => ConfigSharedPrefsClient.java} | 70 ++++---- .../FirebaseRemoteConfigInfoImpl.java | 2 +- .../FirebaseRemoteConfigTest.java | 28 +-- .../RemoteConfigComponentTest.java | 38 +++-- .../remoteconfig/RemoteConfigTests.kt | 4 +- .../remoteconfig/TestConstructorUtil.kt | 6 +- .../internal/ConfigFetchHandlerTest.java | 51 +++--- ....java => ConfigSharedPrefsClientTest.java} | 160 +++++++++--------- .../remoteconfig/ktx/RemoteConfigTests.kt | 4 +- 17 files changed, 267 insertions(+), 250 deletions(-) rename firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/{ConfigMetadataClient.java => ConfigSharedPrefsClient.java} (86%) rename firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/{ConfigMetadataClientTest.java => ConfigSharedPrefsClientTest.java} (66%) diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt index e6167b5ab09..4c153bff1e3 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,8 +23,8 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -41,7 +41,7 @@ fun createRemoteConfig( defaultConfigsCache: ConfigCacheClient, fetchHandler: ConfigFetchHandler, getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigMetadataClient, + frcSharedPrefs: ConfigSharedPrefsClient, realtimeHandler: ConfigRealtimeHandler, rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { @@ -56,7 +56,7 @@ fun createRemoteConfig( defaultConfigsCache, fetchHandler, getHandler, - frcMetadata, + frcSharedPrefs, realtimeHandler, rolloutsStateSubscriptionsHandler ) diff --git a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index bb525cf4090..d3e7d10e725 100644 --- a/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/ktx/src/test/kotlin/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,8 +32,8 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcSharedPrefs = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java index 19900986b6f..cc8c259836e 100644 --- a/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java +++ b/firebase-config/src/androidTest/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigIntegrationTest.java @@ -35,8 +35,8 @@ import com.google.firebase.remoteconfig.internal.ConfigContainer; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.Date; import java.util.HashMap; @@ -60,7 +60,7 @@ public class FirebaseRemoteConfigIntegrationTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigMetadataClient metadataClient; + @Mock private ConfigSharedPrefsClient sharedPrefsClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionHandler; @@ -112,7 +112,7 @@ public void setUp() { mockDefaultsCache, mockFetchHandler, mockGetHandler, - metadataClient, + sharedPrefsClient, mockConfigRealtimeHandler, mockRolloutsStateSubscriptionHandler); } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index ba8f61af7f4..28e5403c213 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -33,8 +33,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.DefaultsXmlParser; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import java.util.ArrayList; @@ -160,7 +160,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { private final ConfigCacheClient defaultConfigsCache; private final ConfigFetchHandler fetchHandler; private final ConfigGetParameterHandler getHandler; - private final ConfigMetadataClient frcMetadata; + private final ConfigSharedPrefsClient frcSharedPrefs; private final FirebaseInstallationsApi firebaseInstallations; private final ConfigRealtimeHandler configRealtimeHandler; private final RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler; @@ -181,7 +181,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { ConfigCacheClient defaultConfigsCache, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigMetadataClient frcMetadata, + ConfigSharedPrefsClient frcSharedPrefs, ConfigRealtimeHandler configRealtimeHandler, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { this.context = context; @@ -194,7 +194,7 @@ public static FirebaseRemoteConfig getInstance(@NonNull FirebaseApp app) { this.defaultConfigsCache = defaultConfigsCache; this.fetchHandler = fetchHandler; this.getHandler = getHandler; - this.frcMetadata = frcMetadata; + this.frcSharedPrefs = frcSharedPrefs; this.configRealtimeHandler = configRealtimeHandler; this.rolloutsStateSubscriptionsHandler = rolloutsStateSubscriptionsHandler; } @@ -208,7 +208,7 @@ public Task ensureInitialized() { Task activatedConfigsTask = activatedConfigsCache.get(); Task defaultsConfigsTask = defaultConfigsCache.get(); Task fetchedConfigsTask = fetchedConfigsCache.get(); - Task metadataTask = Tasks.call(executor, this::getInfo); + Task sharedPrefsTask = Tasks.call(executor, this::getInfo); Task installationIdTask = firebaseInstallations.getId(); Task installationTokenTask = firebaseInstallations.getToken(false); @@ -216,10 +216,10 @@ public Task ensureInitialized() { activatedConfigsTask, defaultsConfigsTask, fetchedConfigsTask, - metadataTask, + sharedPrefsTask, installationIdTask, installationTokenTask) - .continueWith(executor, (unusedListOfCompletedTasks) -> metadataTask.getResult()); + .continueWith(executor, (unusedListOfCompletedTasks) -> sharedPrefsTask.getResult()); } /** @@ -475,7 +475,7 @@ public Map getAll() { */ @NonNull public FirebaseRemoteConfigInfo getInfo() { - return frcMetadata.getInfo(); + return frcSharedPrefs.getInfo(); } /** @@ -488,7 +488,7 @@ public Task setConfigSettingsAsync(@NonNull FirebaseRemoteConfigSettings s return Tasks.call( executor, () -> { - frcMetadata.setConfigSettings(settings); + frcSharedPrefs.setConfigSettings(settings); // Return value required; return null for Void. return null; @@ -548,14 +548,14 @@ public Task setDefaultsAsync(@XmlRes int resourceId) { @NonNull public Task reset() { // Use a Task to avoid throwing potential file I/O errors to the caller and because - // frcMetadata's clear call is blocking. + // frcSharedPrefs's clear call is blocking. return Tasks.call( executor, () -> { activatedConfigsCache.clear(); fetchedConfigsCache.clear(); defaultConfigsCache.clear(); - frcMetadata.clear(); + frcSharedPrefs.clear(); return null; }); } @@ -666,7 +666,7 @@ public Task setCustomSignals(@NonNull CustomSignals customSignalsMap) { return Tasks.call( executor, () -> { - frcMetadata.setCustomSignals(customSignalsMap.customSignals); + frcSharedPrefs.setCustomSignals(customSignalsMap.customSignals); return null; }); } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java index e1e02d5f043..9474414b824 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfigComponent.java @@ -36,8 +36,8 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.ConfigStorageClient; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateFactory; @@ -166,7 +166,7 @@ public synchronized FirebaseRemoteConfig get(String namespace) { ConfigCacheClient fetchedCacheClient = getCacheClient(namespace, FETCH_FILE_NAME); ConfigCacheClient activatedCacheClient = getCacheClient(namespace, ACTIVATE_FILE_NAME); ConfigCacheClient defaultsCacheClient = getCacheClient(namespace, DEFAULTS_FILE_NAME); - ConfigMetadataClient metadataClient = getMetadataClient(context, appId, namespace); + ConfigSharedPrefsClient sharedPrefsClient = getSharedPrefsClient(context, appId, namespace); ConfigGetParameterHandler getHandler = getGetHandler(activatedCacheClient, defaultsCacheClient); Personalization personalization = @@ -187,9 +187,9 @@ public synchronized FirebaseRemoteConfig get(String namespace) { fetchedCacheClient, activatedCacheClient, defaultsCacheClient, - getFetchHandler(namespace, fetchedCacheClient, metadataClient), + getFetchHandler(namespace, fetchedCacheClient, sharedPrefsClient), getHandler, - metadataClient, + sharedPrefsClient, rolloutsStateSubscriptionsHandler); } @@ -206,7 +206,7 @@ synchronized FirebaseRemoteConfig get( ConfigCacheClient defaultsClient, ConfigFetchHandler fetchHandler, ConfigGetParameterHandler getHandler, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient sharedPrefsClient, RolloutsStateSubscriptionsHandler rolloutsStateSubscriptionsHandler) { if (!frcNamespaceInstances.containsKey(namespace)) { FirebaseRemoteConfig in = @@ -221,7 +221,7 @@ synchronized FirebaseRemoteConfig get( defaultsClient, fetchHandler, getHandler, - metadataClient, + sharedPrefsClient, getRealtime( firebaseApp, firebaseInstallations, @@ -229,7 +229,7 @@ synchronized FirebaseRemoteConfig get( activatedClient, context, namespace, - metadataClient), + sharedPrefsClient), rolloutsStateSubscriptionsHandler); in.startLoadingConfigsFromDisk(); frcNamespaceInstances.put(namespace, in); @@ -254,21 +254,23 @@ private ConfigCacheClient getCacheClient(String namespace, String configStoreTyp @VisibleForTesting ConfigFetchHttpClient getFrcBackendApiClient( - String apiKey, String namespace, ConfigMetadataClient metadataClient) { + String apiKey, String namespace, ConfigSharedPrefsClient sharedPrefsClient) { String appId = firebaseApp.getOptions().getApplicationId(); return new ConfigFetchHttpClient( context, appId, apiKey, namespace, - /* connectTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds(), - /* readTimeoutInSeconds= */ metadataClient.getFetchTimeoutInSeconds(), - /* customSignals= */ metadataClient.getCustomSignals()); + /* connectTimeoutInSeconds= */ sharedPrefsClient.getFetchTimeoutInSeconds(), + /* readTimeoutInSeconds= */ sharedPrefsClient.getFetchTimeoutInSeconds(), + /* customSignals= */ sharedPrefsClient.getCustomSignals()); } @VisibleForTesting synchronized ConfigFetchHandler getFetchHandler( - String namespace, ConfigCacheClient fetchedCacheClient, ConfigMetadataClient metadataClient) { + String namespace, + ConfigCacheClient fetchedCacheClient, + ConfigSharedPrefsClient sharedPrefsClient) { return new ConfigFetchHandler( firebaseInstallations, isPrimaryApp(firebaseApp) ? analyticsConnector : () -> null, @@ -276,8 +278,8 @@ synchronized ConfigFetchHandler getFetchHandler( DEFAULT_CLOCK, DEFAULT_RANDOM, fetchedCacheClient, - getFrcBackendApiClient(firebaseApp.getOptions().getApiKey(), namespace, metadataClient), - metadataClient, + getFrcBackendApiClient(firebaseApp.getOptions().getApiKey(), namespace, sharedPrefsClient), + sharedPrefsClient, this.customHeaders); } @@ -288,7 +290,7 @@ synchronized ConfigRealtimeHandler getRealtime( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigMetadataClient metadataClient) { + ConfigSharedPrefsClient sharedPrefsClient) { return new ConfigRealtimeHandler( firebaseApp, firebaseInstallations, @@ -296,7 +298,7 @@ synchronized ConfigRealtimeHandler getRealtime( activatedCacheClient, context, namespace, - metadataClient, + sharedPrefsClient, executor); } @@ -306,13 +308,14 @@ private ConfigGetParameterHandler getGetHandler( } @VisibleForTesting - static ConfigMetadataClient getMetadataClient(Context context, String appId, String namespace) { + static ConfigSharedPrefsClient getSharedPrefsClient( + Context context, String appId, String namespace) { String fileName = String.format( "%s_%s_%s_%s", FIREBASE_REMOTE_CONFIG_FILE_NAME_PREFIX, appId, namespace, PREFERENCES_FILE_NAME); SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); - return new ConfigMetadataClient(preferences); + return new ConfigSharedPrefsClient(preferences); } @Nullable diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java index 7c98589b153..d9103da44f9 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandler.java @@ -14,7 +14,7 @@ package com.google.firebase.remoteconfig.internal; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT; @@ -43,7 +43,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse.Status; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.HttpURLConnection; @@ -96,7 +96,7 @@ public class ConfigFetchHandler { private final Random randomGenerator; private final ConfigCacheClient fetchedConfigsCache; private final ConfigFetchHttpClient frcBackendApiClient; - private final ConfigMetadataClient frcMetadata; + private final ConfigSharedPrefsClient frcSharedPrefs; private final Map customHttpHeaders; @@ -109,7 +109,7 @@ public ConfigFetchHandler( Random randomGenerator, ConfigCacheClient fetchedConfigsCache, ConfigFetchHttpClient frcBackendApiClient, - ConfigMetadataClient frcMetadata, + ConfigSharedPrefsClient frcSharedPrefs, Map customHttpHeaders) { this.firebaseInstallations = firebaseInstallations; this.analyticsConnector = analyticsConnector; @@ -118,16 +118,16 @@ public ConfigFetchHandler( this.randomGenerator = randomGenerator; this.fetchedConfigsCache = fetchedConfigsCache; this.frcBackendApiClient = frcBackendApiClient; - this.frcMetadata = frcMetadata; + this.frcSharedPrefs = frcSharedPrefs; this.customHttpHeaders = customHttpHeaders; } /** * Calls {@link #fetch(long)} with the {@link - * ConfigMetadataClient#getMinimumFetchIntervalInSeconds()}. + * ConfigSharedPrefsClient#getMinimumFetchIntervalInSeconds()}. */ public Task fetch() { - return fetch(frcMetadata.getMinimumFetchIntervalInSeconds()); + return fetch(frcSharedPrefs.getMinimumFetchIntervalInSeconds()); } /** @@ -228,7 +228,7 @@ public Task fetchNowWithTypeAndAttemptNumber( * currently throttled. * *

If a fetch request is made to the backend, updates the last fetch status, last successful - * fetch time and {@link BackoffMetadata} in {@link ConfigMetadataClient}. + * fetch time and {@link BackoffMetadata} in {@link ConfigSharedPrefsClient}. */ private Task fetchIfCacheExpiredAndNotThrottled( Task cachedFetchConfigsTask, @@ -295,7 +295,7 @@ && areCachedFetchConfigsValid(minimumFetchIntervalInSeconds, currentTime)) { * on. */ private boolean areCachedFetchConfigsValid(long cacheExpirationInSeconds, Date newFetchTime) { - Date lastSuccessfulFetchTime = frcMetadata.getLastSuccessfulFetchTime(); + Date lastSuccessfulFetchTime = frcSharedPrefs.getLastSuccessfulFetchTime(); // RC always fetches if the client has not previously had a successful fetch. if (lastSuccessfulFetchTime.equals(LAST_FETCH_TIME_NO_FETCH_YET)) { @@ -315,7 +315,7 @@ private boolean areCachedFetchConfigsValid(long cacheExpirationInSeconds, Date n */ @Nullable private Date getBackoffEndTimeInMillis(Date currentTime) { - Date backoffEndTime = frcMetadata.getBackoffMetadata().getBackoffEndTime(); + Date backoffEndTime = frcSharedPrefs.getBackoffMetadata().getBackoffEndTime(); if (currentTime.before(backoffEndTime)) { return backoffEndTime; } @@ -381,21 +381,22 @@ private FetchResponse fetchFromBackend( installationId, installationToken, getUserProperties(), - frcMetadata.getLastFetchETag(), + frcSharedPrefs.getLastFetchETag(), customFetchHeaders, getFirstOpenTime(), currentTime); if (response.getFetchedConfigs() != null) { // Set template version in metadata to be saved on disk. - frcMetadata.setLastTemplateVersion(response.getFetchedConfigs().getTemplateVersionNumber()); + frcSharedPrefs.setLastTemplateVersion( + response.getFetchedConfigs().getTemplateVersionNumber()); } if (response.getLastFetchETag() != null) { - frcMetadata.setLastFetchETag(response.getLastFetchETag()); + frcSharedPrefs.setLastFetchETag(response.getLastFetchETag()); } // If the execute method did not throw exceptions, then the server sent a successful response // and the client can stop backing off. - frcMetadata.resetBackoff(); + frcSharedPrefs.resetBackoff(); return response; } catch (FirebaseRemoteConfigServerException serverHttpError) { @@ -473,7 +474,7 @@ private BackoffMetadata updateAndReturnBackoffMetadata(int statusCode, Date curr if (isThrottleableServerError(statusCode)) { updateBackoffMetadataWithLastFailedFetchTime(currentTime); } - return frcMetadata.getBackoffMetadata(); + return frcSharedPrefs.getBackoffMetadata(); } /** @@ -497,14 +498,14 @@ private boolean isThrottleableServerError(int httpStatusCode) { * disk-backed metadata. */ private void updateBackoffMetadataWithLastFailedFetchTime(Date lastFailedFetchTime) { - int numFailedFetches = frcMetadata.getBackoffMetadata().getNumFailedFetches(); + int numFailedFetches = frcSharedPrefs.getBackoffMetadata().getNumFailedFetches(); numFailedFetches++; long backoffDurationInMillis = getRandomizedBackoffDurationInMillis(numFailedFetches); Date backoffEndTime = new Date(lastFailedFetchTime.getTime() + backoffDurationInMillis); - frcMetadata.setBackoffMetadata(numFailedFetches, backoffEndTime); + frcSharedPrefs.setBackoffMetadata(numFailedFetches, backoffEndTime); } /** @@ -551,7 +552,7 @@ private boolean shouldThrottle(BackoffMetadata backoffMetadata, int httpStatusCo private void updateLastFetchStatusAndTime( Task completedFetchTask, Date fetchTime) { if (completedFetchTask.isSuccessful()) { - frcMetadata.updateLastFetchAsSuccessfulAt(fetchTime); + frcSharedPrefs.updateLastFetchAsSuccessfulAt(fetchTime); return; } @@ -562,9 +563,9 @@ private void updateLastFetchStatusAndTime( } if (fetchException instanceof FirebaseRemoteConfigFetchThrottledException) { - frcMetadata.updateLastFetchAsThrottled(); + frcSharedPrefs.updateLastFetchAsThrottled(); } else { - frcMetadata.updateLastFetchAsFailed(); + frcSharedPrefs.updateLastFetchAsFailed(); } } @@ -602,7 +603,7 @@ private Long getFirstOpenTime() { } public long getTemplateVersionNumber() { - return frcMetadata.getLastTemplateVersion(); + return frcSharedPrefs.getLastTemplateVersion(); } /** Used to verify that the fetch handler is getting Analytics as expected. */ diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java index 53f89a71e8c..5ed1135dfc7 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHandler.java @@ -39,7 +39,7 @@ public class ConfigRealtimeHandler { private final ConfigCacheClient activatedCacheClient; private final Context context; private final String namespace; - private final ConfigMetadataClient metadataClient; + private final ConfigSharedPrefsClient sharedPrefsClient; private final ScheduledExecutorService scheduledExecutorService; public ConfigRealtimeHandler( @@ -49,7 +49,7 @@ public ConfigRealtimeHandler( ConfigCacheClient activatedCacheClient, Context context, String namespace, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient sharedPrefsClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = new LinkedHashSet<>(); @@ -62,7 +62,7 @@ public ConfigRealtimeHandler( context, namespace, listeners, - metadataClient, + sharedPrefsClient, scheduledExecutorService); this.firebaseApp = firebaseApp; @@ -71,7 +71,7 @@ public ConfigRealtimeHandler( this.activatedCacheClient = activatedCacheClient; this.context = context; this.namespace = namespace; - this.metadataClient = metadataClient; + this.sharedPrefsClient = sharedPrefsClient; this.scheduledExecutorService = scheduledExecutorService; } diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java index ef0ef2defc5..2c1c44480e2 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java @@ -110,7 +110,7 @@ public class ConfigRealtimeHttpClient { private final String namespace; private final Random random; private final Clock clock; - private final ConfigMetadataClient metadataClient; + private final ConfigSharedPrefsClient sharedPrefsClient; public ConfigRealtimeHttpClient( FirebaseApp firebaseApp, @@ -120,7 +120,7 @@ public ConfigRealtimeHttpClient( Context context, String namespace, Set listeners, - ConfigMetadataClient metadataClient, + ConfigSharedPrefsClient sharedPrefsClient, ScheduledExecutorService scheduledExecutorService) { this.listeners = listeners; @@ -132,7 +132,7 @@ public ConfigRealtimeHttpClient( // Retrieve number of remaining retries from last session. The minimum retry count being one. httpRetriesRemaining = Math.max( - ORIGINAL_RETRIES - metadataClient.getRealtimeBackoffMetadata().getNumFailedStreams(), + ORIGINAL_RETRIES - sharedPrefsClient.getRealtimeBackoffMetadata().getNumFailedStreams(), 1); clock = DefaultClock.getInstance(); @@ -142,7 +142,7 @@ public ConfigRealtimeHttpClient( this.activatedCache = activatedCache; this.context = context; this.namespace = namespace; - this.metadataClient = metadataClient; + this.sharedPrefsClient = sharedPrefsClient; this.isRealtimeDisabled = false; this.isInBackground = false; } @@ -230,13 +230,13 @@ private synchronized void propagateErrors(FirebaseRemoteConfigException exceptio // Used for Tests only. @SuppressLint("VisibleForTests") public int getNumberOfFailedStreams() { - return metadataClient.getRealtimeBackoffMetadata().getNumFailedStreams(); + return sharedPrefsClient.getRealtimeBackoffMetadata().getNumFailedStreams(); } // Used for Tests only. @SuppressLint("VisibleForTests") public Date getBackoffEndTime() { - return metadataClient.getRealtimeBackoffMetadata().getBackoffEndTime(); + return sharedPrefsClient.getRealtimeBackoffMetadata().getBackoffEndTime(); } // TODO(issues/265): Make this an atomic operation within the Metadata class to avoid possible @@ -248,7 +248,7 @@ public Date getBackoffEndTime() { */ private void updateBackoffMetadataWithLastFailedStreamConnectionTime( Date lastFailedRealtimeStreamTime) { - int numFailedStreams = metadataClient.getRealtimeBackoffMetadata().getNumFailedStreams(); + int numFailedStreams = sharedPrefsClient.getRealtimeBackoffMetadata().getNumFailedStreams(); numFailedStreams++; @@ -256,7 +256,7 @@ private void updateBackoffMetadataWithLastFailedStreamConnectionTime( Date backoffEndTime = new Date(lastFailedRealtimeStreamTime.getTime() + backoffDurationInMillis); - metadataClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); + sharedPrefsClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); } /** @@ -362,7 +362,7 @@ public synchronized void retryHttpConnectionWhenBackoffEnds() { long retrySeconds = Math.max( 0, - metadataClient.getRealtimeBackoffMetadata().getBackoffEndTime().getTime() + sharedPrefsClient.getRealtimeBackoffMetadata().getBackoffEndTime().getTime() - currentTime.getTime()); makeRealtimeHttpConnection(retrySeconds); } @@ -473,8 +473,8 @@ public void beginRealtimeHttpStream() { return; } - ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = - metadataClient.getRealtimeBackoffMetadata(); + ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = + sharedPrefsClient.getRealtimeBackoffMetadata(); Date currentTime = new Date(clock.currentTimeMillis()); if (currentTime.before(backoffMetadata.getBackoffEndTime())) { retryHttpConnectionWhenBackoffEnds(); @@ -506,7 +506,7 @@ public void beginRealtimeHttpStream() { if (responseCode == HttpURLConnection.HTTP_OK) { // Reset the retries remaining if we opened the connection without an exception. resetRetryCount(); - metadataClient.resetRealtimeBackoff(); + sharedPrefsClient.resetRealtimeBackoff(); // Start listening for realtime notifications. ConfigAutoFetch configAutoFetch = startAutoFetch(httpURLConnection); diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java similarity index 86% rename from firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java rename to firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java index c00dbb069bc..4ee9fd10c16 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java @@ -41,12 +41,12 @@ import org.json.JSONObject; /** - * Client for handling Firebase Remote Config (FRC) metadata that is saved to disk and persisted - * across App life cycles. + * Client for handling Firebase Remote Config (FRC) metadata and custom signals that are saved to + * disk and persisted across App life cycles. * * @author Miraziz Yusupov */ -public class ConfigMetadataClient { +public class ConfigSharedPrefsClient { @Retention(SOURCE) @IntDef({ LAST_FETCH_STATUS_SUCCESS, @@ -90,15 +90,15 @@ public class ConfigMetadataClient { private static final int CUSTOM_SIGNALS_MAX_COUNT = 100; - private final SharedPreferences frcMetadata; + private final SharedPreferences frcSharedPrefs; private final Object frcInfoLock; private final Object backoffMetadataLock; private final Object realtimeBackoffMetadataLock; private final Object customSignalsLock; - public ConfigMetadataClient(SharedPreferences frcMetadata) { - this.frcMetadata = frcMetadata; + public ConfigSharedPrefsClient(SharedPreferences frcSharedPrefs) { + this.frcSharedPrefs = frcSharedPrefs; this.frcInfoLock = new Object(); this.backoffMetadataLock = new Object(); this.realtimeBackoffMetadataLock = new Object(); @@ -106,51 +106,52 @@ public ConfigMetadataClient(SharedPreferences frcMetadata) { } public long getFetchTimeoutInSeconds() { - return frcMetadata.getLong(FETCH_TIMEOUT_IN_SECONDS_KEY, CONNECTION_TIMEOUT_IN_SECONDS); + return frcSharedPrefs.getLong(FETCH_TIMEOUT_IN_SECONDS_KEY, CONNECTION_TIMEOUT_IN_SECONDS); } public long getMinimumFetchIntervalInSeconds() { - return frcMetadata.getLong( + return frcSharedPrefs.getLong( MINIMUM_FETCH_INTERVAL_IN_SECONDS_KEY, DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS); } @LastFetchStatus int getLastFetchStatus() { - return frcMetadata.getInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_NO_FETCH_YET); + return frcSharedPrefs.getInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_NO_FETCH_YET); } Date getLastSuccessfulFetchTime() { return new Date( - frcMetadata.getLong( + frcSharedPrefs.getLong( LAST_SUCCESSFUL_FETCH_TIME_IN_MILLIS_KEY, LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET)); } @Nullable String getLastFetchETag() { - return frcMetadata.getString(LAST_FETCH_ETAG_KEY, null); + return frcSharedPrefs.getString(LAST_FETCH_ETAG_KEY, null); } long getLastTemplateVersion() { - return frcMetadata.getLong(LAST_TEMPLATE_VERSION, 0); + return frcSharedPrefs.getLong(LAST_TEMPLATE_VERSION, 0); } public FirebaseRemoteConfigInfo getInfo() { // A lock is used here to prevent the setters in this class from changing the state of - // frcMetadata during a getInfo call. + // frcSharedPrefs during a getInfo call. synchronized (frcInfoLock) { long lastSuccessfulFetchTimeInMillis = - frcMetadata.getLong( + frcSharedPrefs.getLong( LAST_SUCCESSFUL_FETCH_TIME_IN_MILLIS_KEY, LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET); @LastFetchStatus int lastFetchStatus = - frcMetadata.getInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_NO_FETCH_YET); + frcSharedPrefs.getInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_NO_FETCH_YET); FirebaseRemoteConfigSettings settings = new FirebaseRemoteConfigSettings.Builder() .setFetchTimeoutInSeconds( - frcMetadata.getLong(FETCH_TIMEOUT_IN_SECONDS_KEY, CONNECTION_TIMEOUT_IN_SECONDS)) + frcSharedPrefs.getLong( + FETCH_TIMEOUT_IN_SECONDS_KEY, CONNECTION_TIMEOUT_IN_SECONDS)) .setMinimumFetchIntervalInSeconds( - frcMetadata.getLong( + frcSharedPrefs.getLong( MINIMUM_FETCH_INTERVAL_IN_SECONDS_KEY, DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS)) .build(); @@ -164,14 +165,14 @@ public FirebaseRemoteConfigInfo getInfo() { } /** - * Clears all metadata values from memory and disk. + * Clears all metadata and custom signals values from memory and disk. * *

The method is blocking and returns only when the values in disk are also cleared. */ @WorkerThread public void clear() { synchronized (frcInfoLock) { - frcMetadata.edit().clear().commit(); + frcSharedPrefs.edit().clear().commit(); } } @@ -184,7 +185,7 @@ public void clear() { @WorkerThread public void setConfigSettings(FirebaseRemoteConfigSettings settings) { synchronized (frcInfoLock) { - frcMetadata + frcSharedPrefs .edit() .putLong(FETCH_TIMEOUT_IN_SECONDS_KEY, settings.getFetchTimeoutInSeconds()) .putLong( @@ -201,7 +202,7 @@ public void setConfigSettings(FirebaseRemoteConfigSettings settings) { */ public void setConfigSettingsWithoutWaitingOnDiskWrite(FirebaseRemoteConfigSettings settings) { synchronized (frcInfoLock) { - frcMetadata + frcSharedPrefs .edit() .putLong(FETCH_TIMEOUT_IN_SECONDS_KEY, settings.getFetchTimeoutInSeconds()) .putLong( @@ -212,7 +213,7 @@ public void setConfigSettingsWithoutWaitingOnDiskWrite(FirebaseRemoteConfigSetti void updateLastFetchAsSuccessfulAt(Date fetchTime) { synchronized (frcInfoLock) { - frcMetadata + frcSharedPrefs .edit() .putInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_SUCCESS) .putLong(LAST_SUCCESSFUL_FETCH_TIME_IN_MILLIS_KEY, fetchTime.getTime()) @@ -222,25 +223,25 @@ void updateLastFetchAsSuccessfulAt(Date fetchTime) { void updateLastFetchAsFailed() { synchronized (frcInfoLock) { - frcMetadata.edit().putInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_FAILURE).apply(); + frcSharedPrefs.edit().putInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_FAILURE).apply(); } } void updateLastFetchAsThrottled() { synchronized (frcInfoLock) { - frcMetadata.edit().putInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_THROTTLED).apply(); + frcSharedPrefs.edit().putInt(LAST_FETCH_STATUS_KEY, LAST_FETCH_STATUS_THROTTLED).apply(); } } void setLastFetchETag(String eTag) { synchronized (frcInfoLock) { - frcMetadata.edit().putString(LAST_FETCH_ETAG_KEY, eTag).apply(); + frcSharedPrefs.edit().putString(LAST_FETCH_ETAG_KEY, eTag).apply(); } } void setLastTemplateVersion(long templateVersion) { synchronized (frcInfoLock) { - frcMetadata.edit().putLong(LAST_TEMPLATE_VERSION, templateVersion).apply(); + frcSharedPrefs.edit().putLong(LAST_TEMPLATE_VERSION, templateVersion).apply(); } } @@ -251,14 +252,15 @@ void setLastTemplateVersion(long templateVersion) { BackoffMetadata getBackoffMetadata() { synchronized (backoffMetadataLock) { return new BackoffMetadata( - frcMetadata.getInt(NUM_FAILED_FETCHES_KEY, NO_FAILED_FETCHES), - new Date(frcMetadata.getLong(BACKOFF_END_TIME_IN_MILLIS_KEY, NO_BACKOFF_TIME_IN_MILLIS))); + frcSharedPrefs.getInt(NUM_FAILED_FETCHES_KEY, NO_FAILED_FETCHES), + new Date( + frcSharedPrefs.getLong(BACKOFF_END_TIME_IN_MILLIS_KEY, NO_BACKOFF_TIME_IN_MILLIS))); } } void setBackoffMetadata(int numFailedFetches, Date backoffEndTime) { synchronized (backoffMetadataLock) { - frcMetadata + frcSharedPrefs .edit() .putInt(NUM_FAILED_FETCHES_KEY, numFailedFetches) .putLong(BACKOFF_END_TIME_IN_MILLIS_KEY, backoffEndTime.getTime()) @@ -308,7 +310,7 @@ public void setCustomSignals(Map newCustomSignals) { return; } - frcMetadata + frcSharedPrefs .edit() .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) .commit(); @@ -316,7 +318,7 @@ public void setCustomSignals(Map newCustomSignals) { } public Map getCustomSignals() { - String jsonString = frcMetadata.getString(CUSTOM_SIGNALS, "{}"); + String jsonString = frcSharedPrefs.getString(CUSTOM_SIGNALS, "{}"); try { JSONObject existingCustomSignalsJson = new JSONObject(jsonString); Map custom_signals = new HashMap<>(); @@ -369,16 +371,16 @@ Date getBackoffEndTime() { public RealtimeBackoffMetadata getRealtimeBackoffMetadata() { synchronized (realtimeBackoffMetadataLock) { return new RealtimeBackoffMetadata( - frcMetadata.getInt(NUM_FAILED_REALTIME_STREAMS_KEY, NO_FAILED_REALTIME_STREAMS), + frcSharedPrefs.getInt(NUM_FAILED_REALTIME_STREAMS_KEY, NO_FAILED_REALTIME_STREAMS), new Date( - frcMetadata.getLong( + frcSharedPrefs.getLong( REALTIME_BACKOFF_END_TIME_IN_MILLIS_KEY, NO_BACKOFF_TIME_IN_MILLIS))); } } void setRealtimeBackoffMetadata(int numFailedStreams, Date backoffEndTime) { synchronized (realtimeBackoffMetadataLock) { - frcMetadata + frcSharedPrefs .edit() .putInt(NUM_FAILED_REALTIME_STREAMS_KEY, numFailedStreams) .putLong(REALTIME_BACKOFF_END_TIME_IN_MILLIS_KEY, backoffEndTime.getTime()) diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java index 15f0bb00028..4a16f7bf4e9 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/FirebaseRemoteConfigInfoImpl.java @@ -16,7 +16,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; /** * Impl class for FirebaseRemoteConfigInfo. diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 81f292a4c2b..5a40ccbe068 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -72,9 +72,9 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler; import com.google.firebase.remoteconfig.internal.ConfigRealtimeHttpClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.FakeHttpURLConnection; import com.google.firebase.remoteconfig.internal.Personalization; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; @@ -155,7 +155,7 @@ public final class FirebaseRemoteConfigTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetHandler; - @Mock private ConfigMetadataClient metadataClient; + @Mock private ConfigSharedPrefsClient sharedPrefsClient; @Mock private ConfigRealtimeHandler mockConfigRealtimeHandler; @Mock private ConfigAutoFetch mockConfigAutoFetch; @@ -192,7 +192,7 @@ public final class FirebaseRemoteConfigTest { private ConfigContainer realtimeFetchedContainer; private ConfigAutoFetch configAutoFetch; private ConfigRealtimeHttpClient configRealtimeHttpClient; - private ConfigMetadataClient realtimeMetadataClient; + private ConfigSharedPrefsClient realtimeSharedPrefsClient; private FetchResponse firstFetchedContainerResponse; @@ -240,7 +240,7 @@ public void setUp() throws Exception { mockDefaultsCache, mockFetchHandler, mockGetHandler, - metadataClient, + sharedPrefsClient, mockConfigRealtimeHandler, mockRolloutsStateSubscriptionsHandler); @@ -259,7 +259,7 @@ public void setUp() throws Exception { mockFireperfDefaultsCache, mockFireperfFetchHandler, mockFireperfGetHandler, - RemoteConfigComponent.getMetadataClient(context, APP_ID, FIREPERF_NAMESPACE), + RemoteConfigComponent.getSharedPrefsClient(context, APP_ID, FIREPERF_NAMESPACE), mockRolloutsStateSubscriptionsHandler); personalizationFrc = @@ -276,7 +276,8 @@ public void setUp() throws Exception { mockDefaultsCache, mockFetchHandler, parameterHandler, - RemoteConfigComponent.getMetadataClient(context, APP_ID, PERSONALIZATION_NAMESPACE), + RemoteConfigComponent.getSharedPrefsClient( + context, APP_ID, PERSONALIZATION_NAMESPACE), mockRolloutsStateSubscriptionsHandler); firstFetchedContainer = @@ -349,8 +350,9 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { listeners, mockRetryListener, scheduledExecutorService); - realtimeMetadataClient = - new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + realtimeSharedPrefsClient = + new ConfigSharedPrefsClient( + context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); configRealtimeHttpClient = new ConfigRealtimeHttpClient( firebaseApp, @@ -360,7 +362,7 @@ public void onError(@NonNull FirebaseRemoteConfigException error) { context, "firebase", listeners, - realtimeMetadataClient, + realtimeSharedPrefsClient, scheduledExecutorService); } @@ -1024,7 +1026,7 @@ public void getLong_fireperfNamespace_keyExists_returnsRemoteValue() { @Test public void getInfo_returnsInfo() { - when(metadataClient.getInfo()).thenReturn(mockFrcInfo); + when(sharedPrefsClient.getInfo()).thenReturn(mockFrcInfo); long fetchTimeInMillis = 100L; int lastFetchStatus = LAST_FETCH_STATUS_THROTTLED; @@ -1071,11 +1073,11 @@ public void clear_hasSettings_clearsEverything() { verify(mockActivatedCache).clear(); verify(mockFetchedCache).clear(); verify(mockDefaultsCache).clear(); - verify(metadataClient).clear(); + verify(sharedPrefsClient).clear(); } @Test - public void setConfigSettingsAsync_updatesMetadata() { + public void setConfigSettingsAsync_updatesSharedPrefs() { long fetchTimeout = 13L; long minimumFetchInterval = 666L; FirebaseRemoteConfigSettings frcSettings = @@ -1087,7 +1089,7 @@ public void setConfigSettingsAsync_updatesMetadata() { Task setterTask = frc.setConfigSettingsAsync(frcSettings); assertThat(setterTask.isSuccessful()).isTrue(); - verify(metadataClient).setConfigSettings(frcSettings); + verify(sharedPrefsClient).setConfigSettings(frcSettings); } @Test diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java index c6869267a4d..e0ee9220855 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigComponentTest.java @@ -39,7 +39,7 @@ import com.google.firebase.remoteconfig.internal.ConfigFetchHandler; import com.google.firebase.remoteconfig.internal.ConfigFetchHttpClient; import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient; import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler; import com.google.firebase.remoteconfig.interop.rollouts.RolloutsStateSubscriber; import java.util.Date; @@ -73,7 +73,7 @@ public class RemoteConfigComponentTest { @Mock private ConfigCacheClient mockDefaultsCache; @Mock private ConfigFetchHandler mockFetchHandler; @Mock private ConfigGetParameterHandler mockGetParameterHandler; - @Mock private ConfigMetadataClient mockMetadataClient; + @Mock private ConfigSharedPrefsClient mockSharedPrefsClient; @Mock private RolloutsStateSubscriptionsHandler mockRolloutsStateSubscriptionsHandler; @Mock private RolloutsStateSubscriber mockRolloutsStateSubscriber; @@ -82,7 +82,7 @@ public class RemoteConfigComponentTest { private ExecutorService directExecutor; private ScheduledExecutorService scheduledExecutorService; private FirebaseApp defaultApp; - private ConfigMetadataClient metadataClient; + private ConfigSharedPrefsClient sharedPrefsClient; @Before public void setUp() { @@ -94,7 +94,8 @@ public void setUp() { defaultApp = initializeFirebaseApp(context); - metadataClient = RemoteConfigComponent.getMetadataClient(context, APP_ID, "personalization"); + sharedPrefsClient = + RemoteConfigComponent.getSharedPrefsClient(context, APP_ID, "personalization"); when(mockFirebaseApp.getOptions()) .thenReturn(new FirebaseOptions.Builder().setApplicationId(APP_ID).build()); @@ -106,7 +107,7 @@ public void setUp() { public void frc2p_doesNotCallAbt() throws Exception { FirebaseRemoteConfig fireperfFrc = - getFrcInstanceFromComponentWithMetadataClient( + getFrcInstanceFromComponentWithSharedPrefsClient( getNewFrcComponent(), /* namespace= */ "fireperf"); loadConfigsWithExperimentsForActivate(); @@ -123,7 +124,7 @@ public void frcNonMainFirebaseApp_doesNotCallAbt() throws Exception { when(mockFirebaseApp.getName()).thenReturn("secondary"); FirebaseRemoteConfig frc = - getFrcInstanceFromComponentWithMetadataClient( + getFrcInstanceFromComponentWithSharedPrefsClient( getNewFrcComponentWithoutLoadingDefault(), DEFAULT_NAMESPACE); loadConfigsWithExperimentsForActivate(); @@ -139,7 +140,7 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { ConfigFetchHandler fetchHandler = getNewFrcComponent() - .getFetchHandler(DEFAULT_NAMESPACE, mockFetchedCache, mockMetadataClient); + .getFetchHandler(DEFAULT_NAMESPACE, mockFetchedCache, mockSharedPrefsClient); assertThat(fetchHandler.getAnalyticsConnector().get()).isNull(); } @@ -149,10 +150,12 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { getFrcBackendApiClient_fetchTimeoutIsNotSet_buildsConfigFetchHttpClientWithDefaultConnectionTimeout() { RemoteConfigComponent frcComponent = defaultApp.get(RemoteConfigComponent.class); - when(mockMetadataClient.getFetchTimeoutInSeconds()).thenReturn(CONNECTION_TIMEOUT_IN_SECONDS); + when(mockSharedPrefsClient.getFetchTimeoutInSeconds()) + .thenReturn(CONNECTION_TIMEOUT_IN_SECONDS); ConfigFetchHttpClient frcBackendClient = - frcComponent.getFrcBackendApiClient(DUMMY_API_KEY, DEFAULT_NAMESPACE, mockMetadataClient); + frcComponent.getFrcBackendApiClient( + DUMMY_API_KEY, DEFAULT_NAMESPACE, mockSharedPrefsClient); int actualConnectTimeout = getConnectTimeoutInSeconds(frcBackendClient); int actualReadTimeout = getReadTimeoutInSeconds(frcBackendClient); @@ -167,11 +170,12 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { RemoteConfigComponent frcComponent = defaultApp.get(RemoteConfigComponent.class); long customConnectionTimeoutInSeconds = 2 * CONNECTION_TIMEOUT_IN_SECONDS; - when(mockMetadataClient.getFetchTimeoutInSeconds()) + when(mockSharedPrefsClient.getFetchTimeoutInSeconds()) .thenReturn(customConnectionTimeoutInSeconds); ConfigFetchHttpClient frcBackendClient = - frcComponent.getFrcBackendApiClient(DUMMY_API_KEY, DEFAULT_NAMESPACE, mockMetadataClient); + frcComponent.getFrcBackendApiClient( + DUMMY_API_KEY, DEFAULT_NAMESPACE, mockSharedPrefsClient); int actualConnectTimeout = getConnectTimeoutInSeconds(frcBackendClient); int actualReadTimeout = getReadTimeoutInSeconds(frcBackendClient); @@ -181,9 +185,9 @@ public void getFetchHandler_nonMainFirebaseApp_doesNotUseAnalytics() { @Test public void registerRolloutsStateSubscriber_firebaseNamespace_callsSubscriptionHandler() { - // Mock metadata client response since Realtime handler can't be mocked here. - when(mockMetadataClient.getRealtimeBackoffMetadata()) - .thenReturn(new ConfigMetadataClient.RealtimeBackoffMetadata(0, new Date())); + // Mock shared preference client response since Realtime handler can't be mocked here. + when(mockSharedPrefsClient.getRealtimeBackoffMetadata()) + .thenReturn(new ConfigSharedPrefsClient.RealtimeBackoffMetadata(0, new Date())); RemoteConfigComponent frcComponent = getNewFrcComponentWithoutLoadingDefault(); FirebaseRemoteConfig instance = getFrcInstanceFromComponent(frcComponent, DEFAULT_NAMESPACE); @@ -216,7 +220,7 @@ private RemoteConfigComponent getNewFrcComponentWithoutLoadingDefault() { /* loadGetDefault= */ false); } - private FirebaseRemoteConfig getFrcInstanceFromComponentWithMetadataClient( + private FirebaseRemoteConfig getFrcInstanceFromComponentWithSharedPrefsClient( RemoteConfigComponent frcComponent, String namespace) { return frcComponent.get( mockFirebaseApp, @@ -229,7 +233,7 @@ private FirebaseRemoteConfig getFrcInstanceFromComponentWithMetadataClient( mockDefaultsCache, mockFetchHandler, mockGetParameterHandler, - metadataClient, + sharedPrefsClient, mockRolloutsStateSubscriptionsHandler); } @@ -246,7 +250,7 @@ private FirebaseRemoteConfig getFrcInstanceFromComponent( mockDefaultsCache, mockFetchHandler, mockGetParameterHandler, - mockMetadataClient, + mockSharedPrefsClient, mockRolloutsStateSubscriptionsHandler); } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index 7624ee3827d..84b71905629 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -29,8 +29,8 @@ import com.google.firebase.platforminfo.UserAgentPublisher import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -139,7 +139,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcSharedPrefs = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt index e6167b5ab09..4c153bff1e3 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/TestConstructorUtil.kt @@ -23,8 +23,8 @@ import com.google.firebase.installations.FirebaseInstallationsApi import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import java.util.concurrent.Executor @@ -41,7 +41,7 @@ fun createRemoteConfig( defaultConfigsCache: ConfigCacheClient, fetchHandler: ConfigFetchHandler, getHandler: ConfigGetParameterHandler, - frcMetadata: ConfigMetadataClient, + frcSharedPrefs: ConfigSharedPrefsClient, realtimeHandler: ConfigRealtimeHandler, rolloutsStateSubscriptionsHandler: RolloutsStateSubscriptionsHandler ): FirebaseRemoteConfig { @@ -56,7 +56,7 @@ fun createRemoteConfig( defaultConfigsCache, fetchHandler, getHandler, - frcMetadata, + frcSharedPrefs, realtimeHandler, rolloutsStateSubscriptionsHandler ) diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java index ed2781710fd..28f1278e084 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigFetchHandlerTest.java @@ -29,9 +29,9 @@ import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FIRST_OPEN_TIME_KEY; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.HTTP_TOO_MANY_REQUESTS; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; import static com.google.firebase.remoteconfig.testutil.Assert.assertThrows; import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; @@ -70,7 +70,7 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfigServerException; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; import com.google.firebase.remoteconfig.internal.ConfigFetchHandler.FetchResponse; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; @@ -127,7 +127,7 @@ public class ConfigFetchHandlerTest { private Context context; @Mock private FirebaseInstallationsApi mockFirebaseInstallations; - private ConfigMetadataClient metadataClient; + private ConfigSharedPrefsClient sharedPrefsClient; private ConfigFetchHandler fetchHandler; @@ -142,8 +142,9 @@ public void setUp() throws Exception { directExecutor = MoreExecutors.directExecutor(); context = ApplicationProvider.getApplicationContext(); mockClock = new MockClock(0L); - metadataClient = - new ConfigMetadataClient(context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); + sharedPrefsClient = + new ConfigSharedPrefsClient( + context.getSharedPreferences("test_file", Context.MODE_PRIVATE)); loadBackendApiClient(); loadInstallationIdAndAuthToken(); @@ -549,7 +550,7 @@ public void fetch_getsMultipleFailedResponsesFromServer_resetsBackoffAfterSucces assertWithMessage("Fetch() failed!").that(fetchTask.isSuccessful()).isTrue(); - BackoffMetadata backoffMetadata = metadataClient.getBackoffMetadata(); + BackoffMetadata backoffMetadata = sharedPrefsClient.getBackoffMetadata(); assertThat(backoffMetadata.getNumFailedFetches()).isEqualTo(NO_FAILED_FETCHES); assertThat(backoffMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); } @@ -706,8 +707,9 @@ public void fetch_firstAndOnlyFetchFails_metadataFailStatusAndNoFetchYetTime() t fetchHandler.fetch(); - assertThat(metadataClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_FAILURE); - assertThat(metadataClient.getLastSuccessfulFetchTime()).isEqualTo(LAST_FETCH_TIME_NO_FETCH_YET); + assertThat(sharedPrefsClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_FAILURE); + assertThat(sharedPrefsClient.getLastSuccessfulFetchTime()) + .isEqualTo(LAST_FETCH_TIME_NO_FETCH_YET); } @Test @@ -716,8 +718,8 @@ public void fetch_fetchSucceeds_metadataSuccessStatusAndFetchTimeUpdated() throw fetchHandler.fetch(); - assertThat(metadataClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_SUCCESS); - assertThat(metadataClient.getLastSuccessfulFetchTime()) + assertThat(sharedPrefsClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_SUCCESS); + assertThat(sharedPrefsClient.getLastSuccessfulFetchTime()) .isEqualTo(firstFetchedContainer.getFetchTime()); } @@ -731,8 +733,8 @@ public void fetch_firstFetchSucceedsSecondFetchFails_failStatusAndFirstFetchTime fetchHandler.fetch(/* minimumFetchIntervalInSeconds= */ 0); - assertThat(metadataClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_FAILURE); - assertThat(metadataClient.getLastSuccessfulFetchTime()) + assertThat(sharedPrefsClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_FAILURE); + assertThat(sharedPrefsClient.getLastSuccessfulFetchTime()) .isEqualTo(firstFetchedContainer.getFetchTime()); } @@ -745,8 +747,8 @@ public void getInfo_twoFetchesSucceed_successStatusAndSecondFetchTime() throws E fetchHandler.fetch(/* minimumFetchIntervalInSeconds= */ 0); - assertThat(metadataClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_SUCCESS); - assertThat(metadataClient.getLastSuccessfulFetchTime()) + assertThat(sharedPrefsClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_SUCCESS); + assertThat(sharedPrefsClient.getLastSuccessfulFetchTime()) .isEqualTo(secondFetchedContainer.getFetchTime()); } @@ -759,8 +761,8 @@ public void getInfo_hitsThrottleLimit_throttledStatus() throws Exception { fetchHandler.fetch(/* minimumFetchIntervalInSeconds= */ 0); - assertThat(metadataClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_THROTTLED); - assertThat(metadataClient.getLastSuccessfulFetchTime()) + assertThat(sharedPrefsClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_THROTTLED); + assertThat(sharedPrefsClient.getLastSuccessfulFetchTime()) .isEqualTo(firstFetchedContainer.getFetchTime()); } @@ -775,7 +777,7 @@ private ConfigFetchHandler getNewFetchHandler(AnalyticsConnector analyticsConnec mockRandom, mockFetchedCache, mockBackendFetchApiClient, - metadataClient, + sharedPrefsClient, /* customHttpHeaders= */ ImmutableMap.of())); return fetchHandler; } @@ -875,7 +877,8 @@ private void callFetchAssertThrottledAndAdvanceClock(int httpCode) throws Except long backoffDurationInMillis = loadAndGetNextBackoffDuration( - /* numFailedFetches= */ metadataClient.getBackoffMetadata().getNumFailedFetches() + 1); + /* numFailedFetches= */ sharedPrefsClient.getBackoffMetadata().getNumFailedFetches() + + 1); assertThrowsThrottledException(fetchHandler.fetch(/* minimumFetchIntervalInSeconds= */ 0L)); @@ -900,7 +903,7 @@ private long loadAndGetNextBackoffDuration(int numFailedFetches) { } private void setMinimumFetchIntervalInMetadata(long minimumFetchIntervalInSeconds) { - metadataClient.setConfigSettings( + sharedPrefsClient.setConfigSettings( new FirebaseRemoteConfigSettings.Builder() .setMinimumFetchIntervalInSeconds(minimumFetchIntervalInSeconds) .build()); @@ -957,7 +960,7 @@ private void verifyETags(@Nullable String requestETag, String responseETag) thro /* customHeaders= */ any(), /* firstOpenTime= */ any(), /* currentTime= */ any()); - assertThat(metadataClient.getLastFetchETag()).isEqualTo(responseETag); + assertThat(sharedPrefsClient.getLastFetchETag()).isEqualTo(responseETag); } private void loadBackendApiClient() throws Exception { @@ -966,7 +969,7 @@ private void loadBackendApiClient() throws Exception { } private void loadETags(String requestETag, String responseETag) { - metadataClient.setLastFetchETag(requestETag); + sharedPrefsClient.setLastFetchETag(requestETag); this.responseETag = responseETag; } @@ -981,7 +984,7 @@ private void loadCacheAndClockWithConfig( when(cacheClient.getBlocking()).thenReturn(container); when(cacheClient.get()).thenReturn(Tasks.forResult(container)); mockClock.setCurrentTime(container.getFetchTime().getTime()); - metadataClient.updateLastFetchAsSuccessfulAt(container.getFetchTime()); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(container.getFetchTime()); } private static void cachePutReturnsConfig( diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java similarity index 66% rename from firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java rename to firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java index abbec094298..01f483b3d0e 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigMetadataClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java @@ -21,10 +21,10 @@ import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.LAST_FETCH_STATUS_THROTTLED; import static com.google.firebase.remoteconfig.RemoteConfigComponent.CONNECTION_TIMEOUT_IN_SECONDS; import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LAST_FETCH_TIME_NO_FETCH_YET; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_BACKOFF_TIME; -import static com.google.firebase.remoteconfig.internal.ConfigMetadataClient.NO_FAILED_FETCHES; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LAST_FETCH_TIME_NO_FETCH_YET; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_BACKOFF_TIME; +import static com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.NO_FAILED_FETCHES; import android.content.Context; import android.content.SharedPreferences; @@ -33,8 +33,8 @@ import com.google.common.collect.ImmutableMap; import com.google.firebase.remoteconfig.FirebaseRemoteConfigInfo; import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.BackoffMetadata; -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient.LastFetchStatus; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.BackoffMetadata; +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient.LastFetchStatus; import java.util.Collections; import java.util.Date; import java.util.HashMap; @@ -46,121 +46,123 @@ import org.robolectric.annotation.Config; /** - * Unit tests for the {@link ConfigMetadataClient}. + * Unit tests for the {@link ConfigSharedPrefsClient}. * * @author Miraziz Yusupov */ @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class ConfigMetadataClientTest { - private ConfigMetadataClient metadataClient; +public class ConfigSharedPrefsClientTest { + private ConfigSharedPrefsClient sharedPrefsClient; private FirebaseRemoteConfigSettings.Builder settingsBuilder; @Before public void setUp() { - SharedPreferences metadata = + SharedPreferences sharedPrefs = ApplicationProvider.getApplicationContext() .getSharedPreferences("TEST_FILE_NAME", Context.MODE_PRIVATE); - metadata.edit().clear().commit(); + sharedPrefs.edit().clear().commit(); - metadataClient = new ConfigMetadataClient(metadata); + sharedPrefsClient = new ConfigSharedPrefsClient(sharedPrefs); settingsBuilder = new FirebaseRemoteConfigSettings.Builder(); } @Test public void getFetchTimeoutInSeconds_isNotSet_returnsDefault() { - assertThat(metadataClient.getFetchTimeoutInSeconds()).isEqualTo(CONNECTION_TIMEOUT_IN_SECONDS); + assertThat(sharedPrefsClient.getFetchTimeoutInSeconds()) + .isEqualTo(CONNECTION_TIMEOUT_IN_SECONDS); } @Test public void getFetchTimeoutInSeconds_isSetTo10Seconds_returns10Seconds() { long expectedFetchTimeout = 10L; - metadataClient.setConfigSettings( + sharedPrefsClient.setConfigSettings( settingsBuilder.setFetchTimeoutInSeconds(expectedFetchTimeout).build()); - long fetchTimeout = metadataClient.getFetchTimeoutInSeconds(); + long fetchTimeout = sharedPrefsClient.getFetchTimeoutInSeconds(); assertThat(fetchTimeout).isEqualTo(expectedFetchTimeout); } @Test public void getMinimumFetchIntervalInSeconds_isNotSet_returnsDefault() { - assertThat(metadataClient.getMinimumFetchIntervalInSeconds()) + assertThat(sharedPrefsClient.getMinimumFetchIntervalInSeconds()) .isEqualTo(DEFAULT_MINIMUM_FETCH_INTERVAL_IN_SECONDS); } @Test public void getMinimumFetchIntervalInSeconds_isSetTo10Seconds_returns10Seconds() { long expectedMinimumFetchInterval = 10L; - metadataClient.setConfigSettings( + sharedPrefsClient.setConfigSettings( settingsBuilder.setMinimumFetchIntervalInSeconds(expectedMinimumFetchInterval).build()); - long minimumFetchInterval = metadataClient.getMinimumFetchIntervalInSeconds(); + long minimumFetchInterval = sharedPrefsClient.getMinimumFetchIntervalInSeconds(); assertThat(minimumFetchInterval).isEqualTo(expectedMinimumFetchInterval); } @Test public void getLastFetchStatus_isNotSet_returnsZero() { - assertThat(metadataClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_NO_FETCH_YET); + assertThat(sharedPrefsClient.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_NO_FETCH_YET); } @Test public void getLastFetchStatus_isSetToSuccess_returnsSuccess() { - metadataClient.updateLastFetchAsSuccessfulAt(new Date(100L)); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(new Date(100L)); - @LastFetchStatus int lastFetchStatus = metadataClient.getLastFetchStatus(); + @LastFetchStatus int lastFetchStatus = sharedPrefsClient.getLastFetchStatus(); assertThat(lastFetchStatus).isEqualTo(LAST_FETCH_STATUS_SUCCESS); } @Test public void getLastSuccessfulFetchTime_isNotSet_returnsZero() { - assertThat(metadataClient.getLastSuccessfulFetchTime()).isEqualTo(LAST_FETCH_TIME_NO_FETCH_YET); + assertThat(sharedPrefsClient.getLastSuccessfulFetchTime()) + .isEqualTo(LAST_FETCH_TIME_NO_FETCH_YET); } @Test public void getLastSuccessfulFetchTime_isSet_returnsTime() { Date fetchTime = new Date(1000L); - metadataClient.updateLastFetchAsSuccessfulAt(fetchTime); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(fetchTime); - Date lastSuccessfulFetchTime = metadataClient.getLastSuccessfulFetchTime(); + Date lastSuccessfulFetchTime = sharedPrefsClient.getLastSuccessfulFetchTime(); assertThat(lastSuccessfulFetchTime).isEqualTo(fetchTime); } @Test public void getLastFetchETag_isNotSet_returnsEmptyString() { - assertThat(metadataClient.getLastFetchETag()).isNull(); + assertThat(sharedPrefsClient.getLastFetchETag()).isNull(); } @Test public void getLastFetchETag_isSet_returnsETag() { String expectedETag = "an etag"; - metadataClient.setLastFetchETag(expectedETag); + sharedPrefsClient.setLastFetchETag(expectedETag); - String eTag = metadataClient.getLastFetchETag(); + String eTag = sharedPrefsClient.getLastFetchETag(); assertThat(eTag).isEqualTo(expectedETag); } @Test public void getLastTemplateVersion_isNotSet_returnsDefault() { - assertThat(metadataClient.getLastTemplateVersion()).isEqualTo(0); + assertThat(sharedPrefsClient.getLastTemplateVersion()).isEqualTo(0); } @Test public void getLastTemplateVersion_isSet_returnsTemplateVersion() { - metadataClient.setLastTemplateVersion(1); - assertThat(metadataClient.getLastTemplateVersion()).isEqualTo(1); + sharedPrefsClient.setLastTemplateVersion(1); + assertThat(sharedPrefsClient.getLastTemplateVersion()).isEqualTo(1); } @Test public void getRealtimeBackoffMetadata_isNotSet_returnsNoFailedStreamsAndNotThrottled() { - ConfigMetadataClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = - metadataClient.getRealtimeBackoffMetadata(); + ConfigSharedPrefsClient.RealtimeBackoffMetadata defaultRealtimeBackoffMetadata = + sharedPrefsClient.getRealtimeBackoffMetadata(); assertThat(defaultRealtimeBackoffMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); assertThat(defaultRealtimeBackoffMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); @@ -170,10 +172,10 @@ public void getRealtimeBackoffMetadata_isNotSet_returnsNoFailedStreamsAndNotThro public void getRealtimeBackoffMetadata_hasValues_returnsValues() { int numFailedStreams = 5; Date backoffEndTime = new Date(1000L); - metadataClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); + sharedPrefsClient.setRealtimeBackoffMetadata(numFailedStreams, backoffEndTime); - ConfigMetadataClient.RealtimeBackoffMetadata backoffMetadata = - metadataClient.getRealtimeBackoffMetadata(); + ConfigSharedPrefsClient.RealtimeBackoffMetadata backoffMetadata = + sharedPrefsClient.getRealtimeBackoffMetadata(); assertThat(backoffMetadata.getNumFailedStreams()).isEqualTo(numFailedStreams); assertThat(backoffMetadata.getBackoffEndTime()).isEqualTo(backoffEndTime); @@ -181,26 +183,26 @@ public void getRealtimeBackoffMetadata_hasValues_returnsValues() { @Test public void resetRealtimeBackoff_hasValues_clearsAllValues() { - metadataClient.setRealtimeBackoffMetadata( + sharedPrefsClient.setRealtimeBackoffMetadata( /* numFailedStreams= */ 5, /* backoffEndTime= */ new Date(1000L)); - ConfigMetadataClient.RealtimeBackoffMetadata realtimeBackoffMetadata = - metadataClient.getRealtimeBackoffMetadata(); + ConfigSharedPrefsClient.RealtimeBackoffMetadata realtimeBackoffMetadata = + sharedPrefsClient.getRealtimeBackoffMetadata(); Preconditions.checkArgument(realtimeBackoffMetadata.getNumFailedStreams() != NO_FAILED_FETCHES); Preconditions.checkArgument( !realtimeBackoffMetadata.getBackoffEndTime().equals(NO_BACKOFF_TIME)); - metadataClient.resetRealtimeBackoff(); + sharedPrefsClient.resetRealtimeBackoff(); - ConfigMetadataClient.RealtimeBackoffMetadata resetMetadata = - metadataClient.getRealtimeBackoffMetadata(); + ConfigSharedPrefsClient.RealtimeBackoffMetadata resetMetadata = + sharedPrefsClient.getRealtimeBackoffMetadata(); assertThat(resetMetadata.getNumFailedStreams()).isEqualTo(NO_FAILED_FETCHES); assertThat(resetMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); } @Test public void getBackoffMetadata_isNotSet_returnsNoFailedFetchesAndNotThrottled() { - BackoffMetadata defaultBackoffMetadata = metadataClient.getBackoffMetadata(); + BackoffMetadata defaultBackoffMetadata = sharedPrefsClient.getBackoffMetadata(); assertThat(defaultBackoffMetadata.getNumFailedFetches()).isEqualTo(NO_FAILED_FETCHES); assertThat(defaultBackoffMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); @@ -210,9 +212,9 @@ public void getBackoffMetadata_isNotSet_returnsNoFailedFetchesAndNotThrottled() public void getBackoffMetadata_hasValues_returnsValues() { int numFailedFetches = 5; Date backoffEndTime = new Date(1000L); - metadataClient.setBackoffMetadata(numFailedFetches, backoffEndTime); + sharedPrefsClient.setBackoffMetadata(numFailedFetches, backoffEndTime); - BackoffMetadata backoffMetadata = metadataClient.getBackoffMetadata(); + BackoffMetadata backoffMetadata = sharedPrefsClient.getBackoffMetadata(); assertThat(backoffMetadata.getNumFailedFetches()).isEqualTo(numFailedFetches); assertThat(backoffMetadata.getBackoffEndTime()).isEqualTo(backoffEndTime); @@ -220,23 +222,23 @@ public void getBackoffMetadata_hasValues_returnsValues() { @Test public void resetBackoff_hasValues_clearsAllValues() { - metadataClient.setBackoffMetadata( + sharedPrefsClient.setBackoffMetadata( /* numFailedFetches= */ 5, /* backoffEndTime= */ new Date(1000L)); - BackoffMetadata backoffMetadata = metadataClient.getBackoffMetadata(); + BackoffMetadata backoffMetadata = sharedPrefsClient.getBackoffMetadata(); Preconditions.checkArgument(backoffMetadata.getNumFailedFetches() != NO_FAILED_FETCHES); Preconditions.checkArgument(!backoffMetadata.getBackoffEndTime().equals(NO_BACKOFF_TIME)); - metadataClient.resetBackoff(); + sharedPrefsClient.resetBackoff(); - BackoffMetadata resetMetadata = metadataClient.getBackoffMetadata(); + BackoffMetadata resetMetadata = sharedPrefsClient.getBackoffMetadata(); assertThat(resetMetadata.getNumFailedFetches()).isEqualTo(NO_FAILED_FETCHES); assertThat(resetMetadata.getBackoffEndTime()).isEqualTo(NO_BACKOFF_TIME); } @Test public void getInfo_hasNoSetValues_returnsDefaults() { - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getFetchTimeMillis()).isEqualTo(LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_NO_FETCH_YET); @@ -249,18 +251,18 @@ public void getInfo_hasNoSetValues_returnsDefaults() { @Test public void getInfo_hasSetValues_returnsValues() { Date lastSuccessfulFetchTime = new Date(1000L); - metadataClient.updateLastFetchAsSuccessfulAt(lastSuccessfulFetchTime); - metadataClient.updateLastFetchAsFailed(); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(lastSuccessfulFetchTime); + sharedPrefsClient.updateLastFetchAsFailed(); long fetchTimeout = 666L; long minimumFetchInterval = 666L; - metadataClient.setConfigSettings( + sharedPrefsClient.setConfigSettings( new FirebaseRemoteConfigSettings.Builder() .setFetchTimeoutInSeconds(fetchTimeout) .setMinimumFetchIntervalInSeconds(minimumFetchInterval) .build()); - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getFetchTimeMillis()).isEqualTo(lastSuccessfulFetchTime.getTime()); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_FAILURE); @@ -271,9 +273,9 @@ public void getInfo_hasSetValues_returnsValues() { @Test public void getInfo_firstAndOnlyFetchFails_failStatusAndNoFetchYetTime() { - metadataClient.updateLastFetchAsFailed(); + sharedPrefsClient.updateLastFetchAsFailed(); - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_FAILURE); assertThat(info.getFetchTimeMillis()).isEqualTo(LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET); @@ -282,9 +284,9 @@ public void getInfo_firstAndOnlyFetchFails_failStatusAndNoFetchYetTime() { @Test public void getInfo_fetchSucceeds_successStatusAndFetchTimeUpdated() { Date fetchTime = new Date(100L); - metadataClient.updateLastFetchAsSuccessfulAt(fetchTime); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(fetchTime); - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_SUCCESS); assertThat(info.getFetchTimeMillis()).isEqualTo(fetchTime.getTime()); @@ -293,11 +295,11 @@ public void getInfo_fetchSucceeds_successStatusAndFetchTimeUpdated() { @Test public void getInfo_firstFetchSucceedsSecondFetchFails_failStatusAndFirstFetchTime() { Date fetchTime = new Date(100L); - metadataClient.updateLastFetchAsSuccessfulAt(fetchTime); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(fetchTime); - metadataClient.updateLastFetchAsFailed(); + sharedPrefsClient.updateLastFetchAsFailed(); - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_FAILURE); assertThat(info.getFetchTimeMillis()).isEqualTo(fetchTime.getTime()); @@ -306,12 +308,12 @@ public void getInfo_firstFetchSucceedsSecondFetchFails_failStatusAndFirstFetchTi @Test public void getInfo_twoFetchesSucceed_successStatusAndSecondFetchTime() { Date fetchTime = new Date(100L); - metadataClient.updateLastFetchAsSuccessfulAt(fetchTime); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(fetchTime); Date secondFetchTime = new Date(200L); - metadataClient.updateLastFetchAsSuccessfulAt(secondFetchTime); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(secondFetchTime); - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_SUCCESS); assertThat(info.getFetchTimeMillis()).isEqualTo(secondFetchTime.getTime()); @@ -320,11 +322,11 @@ public void getInfo_twoFetchesSucceed_successStatusAndSecondFetchTime() { @Test public void getInfo_hitsThrottleLimit_throttledStatus() { Date fetchTime = new Date(100L); - metadataClient.updateLastFetchAsSuccessfulAt(fetchTime); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(fetchTime); - metadataClient.updateLastFetchAsThrottled(); + sharedPrefsClient.updateLastFetchAsThrottled(); - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_THROTTLED); assertThat(info.getFetchTimeMillis()).isEqualTo(fetchTime.getTime()); @@ -333,19 +335,19 @@ public void getInfo_hitsThrottleLimit_throttledStatus() { @Test public void clear_hasSetValues_clearsAll() { Date lastSuccessfulFetchTime = new Date(1000L); - metadataClient.updateLastFetchAsSuccessfulAt(lastSuccessfulFetchTime); + sharedPrefsClient.updateLastFetchAsSuccessfulAt(lastSuccessfulFetchTime); long fetchTimeout = 666L; long minimumFetchInterval = 666L; - metadataClient.setConfigSettings( + sharedPrefsClient.setConfigSettings( new FirebaseRemoteConfigSettings.Builder() .setFetchTimeoutInSeconds(fetchTimeout) .setMinimumFetchIntervalInSeconds(minimumFetchInterval) .build()); - metadataClient.clear(); + sharedPrefsClient.clear(); - FirebaseRemoteConfigInfo info = metadataClient.getInfo(); + FirebaseRemoteConfigInfo info = sharedPrefsClient.getInfo(); assertThat(info.getFetchTimeMillis()).isEqualTo(LAST_FETCH_TIME_IN_MILLIS_NO_FETCH_YET); assertThat(info.getLastFetchStatus()).isEqualTo(LAST_FETCH_STATUS_NO_FETCH_YET); assertThat(info.getConfigSettings().getFetchTimeoutInSeconds()) @@ -356,7 +358,7 @@ public void clear_hasSetValues_clearsAll() { @Test public void getCustomSignals_isNotSet_returnsEmptyMap() { - assertThat(metadataClient.getCustomSignals()).isEqualTo(Collections.emptyMap()); + assertThat(sharedPrefsClient.getCustomSignals()).isEqualTo(Collections.emptyMap()); } @Test @@ -365,28 +367,28 @@ public void getCustomSignals_isSet_returnsCustomSignals() { ImmutableMap.of( "subscription", "premium", "age", "20"); - metadataClient.setCustomSignals(SAMPLE_CUSTOM_SIGNALS); - assertThat(metadataClient.getCustomSignals()).isEqualTo(SAMPLE_CUSTOM_SIGNALS); + sharedPrefsClient.setCustomSignals(SAMPLE_CUSTOM_SIGNALS); + assertThat(sharedPrefsClient.getCustomSignals()).isEqualTo(SAMPLE_CUSTOM_SIGNALS); } @Test public void setCustomSignals_multipleTimes_addsNewSignals() { Map signals1 = ImmutableMap.of("subscription", "premium"); Map signals2 = ImmutableMap.of("age", "20"); - metadataClient.setCustomSignals(signals1); - metadataClient.setCustomSignals(signals2); + sharedPrefsClient.setCustomSignals(signals1); + sharedPrefsClient.setCustomSignals(signals2); Map expectedSignals = ImmutableMap.of("subscription", "premium", "age", "20"); - assertThat(metadataClient.getCustomSignals()).isEqualTo(expectedSignals); + assertThat(sharedPrefsClient.getCustomSignals()).isEqualTo(expectedSignals); } @Test public void setCustomSignals_nullValue_removesSignal() { Map signals1 = ImmutableMap.of("subscription", "premium", "age", "20"); - metadataClient.setCustomSignals(signals1); + sharedPrefsClient.setCustomSignals(signals1); Map signals2 = new HashMap<>(); signals2.put("age", null); - metadataClient.setCustomSignals(signals2); + sharedPrefsClient.setCustomSignals(signals2); Map expectedSignals = ImmutableMap.of("subscription", "premium"); - assertThat(metadataClient.getCustomSignals()).isEqualTo(expectedSignals); + assertThat(sharedPrefsClient.getCustomSignals()).isEqualTo(expectedSignals); } } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt index c11ea869fbf..2a423843a7c 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/ktx/RemoteConfigTests.kt @@ -32,8 +32,8 @@ import com.google.firebase.remoteconfig.createRemoteConfig import com.google.firebase.remoteconfig.internal.ConfigCacheClient import com.google.firebase.remoteconfig.internal.ConfigFetchHandler import com.google.firebase.remoteconfig.internal.ConfigGetParameterHandler -import com.google.firebase.remoteconfig.internal.ConfigMetadataClient import com.google.firebase.remoteconfig.internal.ConfigRealtimeHandler +import com.google.firebase.remoteconfig.internal.ConfigSharedPrefsClient import com.google.firebase.remoteconfig.internal.rollouts.RolloutsStateSubscriptionsHandler import org.junit.After import org.junit.Before @@ -142,7 +142,7 @@ class ConfigTests : BaseTestCase() { defaultConfigsCache = mock(ConfigCacheClient::class.java), fetchHandler = mock(ConfigFetchHandler::class.java), getHandler = mockGetHandler, - frcMetadata = mock(ConfigMetadataClient::class.java), + frcSharedPrefs = mock(ConfigSharedPrefsClient::class.java), realtimeHandler = mock(ConfigRealtimeHandler::class.java), rolloutsStateSubscriptionsHandler = mock(RolloutsStateSubscriptionsHandler::class.java) ) From 3e94fe3cfe6bfd97008cd9147c9aeee59933172a Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Tue, 26 Nov 2024 10:32:52 +0530 Subject: [PATCH 15/17] Improve Kotlin API, add logs and tests --- .../firebase/remoteconfig/RemoteConfig.kt | 3 + .../internal/ConfigFetchHttpClient.java | 3 + .../internal/ConfigSharedPrefsClient.java | 3 + .../remoteconfig/CustomSignalsTest.java | 82 +++++++++++++++++++ .../FirebaseRemoteConfigTest.java | 15 ++++ .../remoteconfig/RemoteConfigTests.kt | 55 +++++++++++++ 6 files changed, 161 insertions(+) create mode 100644 firebase-config/src/test/java/com/google/firebase/remoteconfig/CustomSignalsTest.java diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfig.kt b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfig.kt index a944a7e8857..3a7ef220198 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfig.kt +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/RemoteConfig.kt @@ -48,6 +48,9 @@ fun remoteConfigSettings( return builder.build() } +fun customSignals(builder: CustomSignals.Builder.() -> Unit) = + CustomSignals.Builder().apply(builder).build() + /** * Starts listening for config updates from the Remote Config backend and emits [ConfigUpdate]s via * a [Flow]. See [FirebaseRemoteConfig.addOnConfigUpdateListener] for more information. diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java index c0a453cfe79..60863a04326 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigFetchHttpClient.java @@ -353,6 +353,9 @@ private JSONObject createFetchRequestBody( if (!customSignalsMap.isEmpty()) { requestBodyMap.put(CUSTOM_SIGNALS, new JSONObject(customSignalsMap)); + + // Log the custom signals during fetch. + Log.d(TAG, "Fetching with custom signals: " + customSignalsMap); } if (firstOpenTime != null) { diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java index 4ee9fd10c16..c0d6fa0b69b 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClient.java @@ -314,6 +314,9 @@ public void setCustomSignals(Map newCustomSignals) { .edit() .putString(CUSTOM_SIGNALS, new JSONObject(existingCustomSignals).toString()) .commit(); + + // Log the final updated custom signals. + Log.d(TAG, "Updated custom signals: " + getCustomSignals()); } } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/CustomSignalsTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/CustomSignalsTest.java new file mode 100644 index 00000000000..2596363c9a2 --- /dev/null +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/CustomSignalsTest.java @@ -0,0 +1,82 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.firebase.remoteconfig; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +/** Unit tests for the {@link CustomSignals}.*/ +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class CustomSignalsTest { + @Test + public void testCustomSignals_builderPutString() { + CustomSignals customSignals = + new CustomSignals.Builder().put("key1", "value1").put("key2", "value2").build(); + Map expectedSignals = ImmutableMap.of("key1", "value1", "key2", "value2"); + assertEquals(expectedSignals, customSignals.customSignals); + } + + @Test + public void testCustomSignals_builderPutLong() { + CustomSignals customSignals = + new CustomSignals.Builder().put("key1", 123L).put("key2", 456L).build(); + Map expectedSignals = ImmutableMap.of("key1", "123", "key2", "456"); + assertEquals(expectedSignals, customSignals.customSignals); + } + + @Test + public void testCustomSignals_builderPutDouble() { + CustomSignals customSignals = + new CustomSignals.Builder().put("key1", 12.34).put("key2", 56.78).build(); + Map expectedSignals = ImmutableMap.of("key1", "12.34", "key2", "56.78"); + assertEquals(expectedSignals, customSignals.customSignals); + } + + @Test + public void testCustomSignals_builderPutMixedTypes() { + CustomSignals customSignals = + new CustomSignals.Builder() + .put("key1", "value1") + .put("key2", 123L) + .put("key3", 45.67) + .build(); + Map expectedSignals = + ImmutableMap.of("key1", "value1", "key2", "123", "key3", "45.67"); + assertEquals(expectedSignals, customSignals.customSignals); + } + + @Test + public void testCustomSignals_builderPutNullValue() { + CustomSignals customSignals = new CustomSignals.Builder().put("key1", null).build(); + Map expectedSignals = new HashMap<>(); + expectedSignals.put("key1", null); + assertEquals(expectedSignals, customSignals.customSignals); + } + + @Test + public void testCustomSignals_builderEmpty() { + CustomSignals customSignals = new CustomSignals.Builder().build(); + assertTrue(customSignals.customSignals.isEmpty()); + } +} diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 5a40ccbe068..2b4f9b2f8ab 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -1660,6 +1660,21 @@ public void realtimeRequest_setRequestParams_succeedsWithCorrectParams() throws assertThat(fakeConnection.getRequestMethod()).isEqualTo("POST"); } + @Test + public void setCustomSignals_succeeds_and_calls_sharedPrefsClient() { + CustomSignals customSignals = + new CustomSignals.Builder() + .put("key1", "value1") + .put("key2", 123L) + .put("key3", 12.34) + .build(); + + Task setterTask = frc.setCustomSignals(customSignals); + + assertThat(setterTask.isSuccessful()).isTrue(); + verify(sharedPrefsClient).setCustomSignals(customSignals.customSignals); + } + private static void loadCacheWithConfig( ConfigCacheClient cacheClient, ConfigContainer container) { when(cacheClient.getBlocking()).thenReturn(container); diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt index 84b71905629..aa166a1ea81 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/RemoteConfigTests.kt @@ -17,6 +17,7 @@ package com.google.firebase.remoteconfig import androidx.test.core.app.ApplicationProvider +import com.google.common.collect.ImmutableMap import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors import com.google.firebase.Firebase @@ -147,6 +148,60 @@ class ConfigTests : BaseTestCase() { `when`(mockGetHandler.getValue("KEY")).thenReturn(StringRemoteConfigValue("non default value")) assertThat(remoteConfig["KEY"].asString()).isEqualTo("non default value") } + + @Test + fun `Custom Signals builder put string`() { + val customSignals = customSignals { + put("key1", "value1") + put("key2", "value2") + } + val expectedSignals = ImmutableMap.of("key1", "value1", "key2", "value2") + assertThat(customSignals.customSignals).isEqualTo(expectedSignals) + } + + @Test + fun `Custom Signals builder put long`() { + val customSignals = customSignals { + put("key1", 123L) + put("key2", 456L) + } + val expectedSignals = ImmutableMap.of("key1", "123", "key2", "456") + assertThat(customSignals.customSignals).isEqualTo(expectedSignals) + } + + @Test + fun `Custom Signals builder put double`() { + val customSignals = customSignals { + put("key1", 12.34) + put("key2", 56.78) + } + val expectedSignals = ImmutableMap.of("key1", "12.34", "key2", "56.78") + assertThat(customSignals.customSignals).isEqualTo(expectedSignals) + } + + @Test + fun `Custom Signals builder put mixed types`() { + val customSignals = customSignals { + put("key1", "value1") + put("key2", 123L) + put("key3", 45.67) + } + val expectedSignals = ImmutableMap.of("key1", "value1", "key2", "123", "key3", "45.67") + assertThat(customSignals.customSignals).isEqualTo(expectedSignals) + } + + @Test + fun `Custom Signals builder put null value`() { + val customSignals = customSignals { put("key1", null) } + val expectedSignals = mapOf("key1" to null) + assertThat(customSignals.customSignals).isEqualTo(expectedSignals) + } + + @Test + fun `Custom Signals empty builder`() { + val customSignals = customSignals {} + assertThat(customSignals.customSignals).isEmpty() + } } @RunWith(RobolectricTestRunner::class) From 5a41f0dbbf60ee9aea62823ad04a055acc1de54f Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Tue, 26 Nov 2024 10:45:35 +0530 Subject: [PATCH 16/17] Update API definition file to include kotlin --- firebase-config/api.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase-config/api.txt b/firebase-config/api.txt index 07145facb20..58e75c9e18c 100644 --- a/firebase-config/api.txt +++ b/firebase-config/api.txt @@ -133,6 +133,7 @@ package com.google.firebase.remoteconfig { } public final class RemoteConfigKt { + method @NonNull public static com.google.firebase.remoteconfig.CustomSignals customSignals(@NonNull kotlin.jvm.functions.Function1 builder); method @NonNull public static operator com.google.firebase.remoteconfig.FirebaseRemoteConfigValue get(@NonNull com.google.firebase.remoteconfig.FirebaseRemoteConfig, @NonNull String key); method @NonNull public static kotlinx.coroutines.flow.Flow getConfigUpdates(@NonNull com.google.firebase.remoteconfig.FirebaseRemoteConfig); method @NonNull public static com.google.firebase.remoteconfig.FirebaseRemoteConfig getRemoteConfig(@NonNull com.google.firebase.Firebase); From c6b9c564e7747735f9a58a23efd59510f32bd2c3 Mon Sep 17 00:00:00 2001 From: tusharkhandelwal8 Date: Tue, 3 Dec 2024 10:14:28 +0530 Subject: [PATCH 17/17] Update test and rename customSignalsMap to customSignals --- .../google/firebase/remoteconfig/FirebaseRemoteConfig.java | 6 +++--- .../remoteconfig/internal/ConfigSharedPrefsClientTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java index 28e5403c213..50d6c36698a 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/FirebaseRemoteConfig.java @@ -658,15 +658,15 @@ private Task setDefaultsWithStringsMapAsync(Map defaultsSt *

The {@code customSignals} parameter should be an instance of {@link CustomSignals}, which * enforces the allowed types for custom signal values (String, Long or Double). * - * @param customSignalsMap A dictionary of keys and the values of the custom signals to be set for + * @param customSignals A dictionary of keys and the values of the custom signals to be set for * the app instance */ @NonNull - public Task setCustomSignals(@NonNull CustomSignals customSignalsMap) { + public Task setCustomSignals(@NonNull CustomSignals customSignals) { return Tasks.call( executor, () -> { - frcSharedPrefs.setCustomSignals(customSignalsMap.customSignals); + frcSharedPrefs.setCustomSignals(customSignals.customSignals); return null; }); } diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java index 01f483b3d0e..2edfb171ddc 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigSharedPrefsClientTest.java @@ -374,10 +374,10 @@ public void getCustomSignals_isSet_returnsCustomSignals() { @Test public void setCustomSignals_multipleTimes_addsNewSignals() { Map signals1 = ImmutableMap.of("subscription", "premium"); - Map signals2 = ImmutableMap.of("age", "20"); + Map signals2 = ImmutableMap.of("age", "20", "subscription", "basic"); sharedPrefsClient.setCustomSignals(signals1); sharedPrefsClient.setCustomSignals(signals2); - Map expectedSignals = ImmutableMap.of("subscription", "premium", "age", "20"); + Map expectedSignals = ImmutableMap.of("subscription", "basic", "age", "20"); assertThat(sharedPrefsClient.getCustomSignals()).isEqualTo(expectedSignals); }