Add a feature flag to disable SMS megaphone.

As part of this work, we also make sure we fetch feature flags during
registration.
This commit is contained in:
Greyson Parrelli
2021-06-18 10:45:00 -04:00
committed by Cody Henthorne
parent 2d93d74b9f
commit 817f1ee938
5 changed files with 77 additions and 19 deletions

View File

@@ -3,8 +3,8 @@ package org.thoughtcrime.securesms.util;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
import com.annimon.stream.Stream;
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.jobs.RemoteConfigRefreshJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.messageprocessingalarm.MessageProcessReceiver;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -43,7 +44,7 @@ import java.util.concurrent.TimeUnit;
* Other interesting things you can do:
* - Make a flag {@link #HOT_SWAPPABLE}
* - Make a flag {@link #STICKY} -- booleans only!
* - Register a listener for flag changes in {@link #FLAG_CHANGE_LISTENERS}
* - Register a listener for flag changes in {@link #FLAG_CHANGE_LISTENERS}
*/
public final class FeatureFlags {
@@ -78,6 +79,7 @@ public final class FeatureFlags {
private static final String RETRY_RECEIPT_LIFESPAN = "android.retryReceiptLifespan";
private static final String RETRY_RESPOND_MAX_AGE = "android.retryRespondMaxAge";
private static final String SENDER_KEY = "android.senderKey";
private static final String SUGGEST_SMS_BLACKLIST = "android.suggestSmsBlacklist";
/**
* We will only store remote values for flags in this set. If you want a flag to be controllable
@@ -110,7 +112,8 @@ public final class FeatureFlags {
MEDIA_QUALITY_LEVELS,
RETRY_RECEIPT_LIFESPAN,
RETRY_RESPOND_MAX_AGE,
SENDER_KEY
SENDER_KEY,
SUGGEST_SMS_BLACKLIST
);
@VisibleForTesting
@@ -156,7 +159,8 @@ public final class FeatureFlags {
MP4_GIF_SEND_SUPPORT,
MEDIA_QUALITY_LEVELS,
RETRY_RECEIPT_LIFESPAN,
RETRY_RESPOND_MAX_AGE
RETRY_RESPOND_MAX_AGE,
SUGGEST_SMS_BLACKLIST
);
/**
@@ -199,7 +203,7 @@ public final class FeatureFlags {
Log.i(TAG, "init() " + REMOTE_VALUES.toString());
}
public static synchronized void refreshIfNecessary() {
public static void refreshIfNecessary() {
long timeSinceLastFetch = System.currentTimeMillis() - SignalStore.remoteConfigValues().getLastFetchTime();
if (timeSinceLastFetch < 0 || timeSinceLastFetch > FETCH_INTERVAL) {
@@ -210,6 +214,12 @@ public final class FeatureFlags {
}
}
@WorkerThread
public static void refreshSync() throws IOException {
Map<String, Object> config = ApplicationDependencies.getSignalServiceAccountManager().getRemoteConfig();
FeatureFlags.update(config);
}
public static synchronized void update(@NonNull Map<String, Object> config) {
Map<String, Object> memory = REMOTE_VALUES;
Map<String, Object> disk = parseStoredConfig(SignalStore.remoteConfigValues().getPendingConfig());
@@ -333,7 +343,7 @@ public final class FeatureFlags {
return getBoolean(MP4_GIF_SEND_SUPPORT, false);
}
public static @Nullable String getMediaQualityLevels() {
public static @NonNull String getMediaQualityLevels() {
return getString(MEDIA_QUALITY_LEVELS, "");
}
@@ -352,6 +362,11 @@ public final class FeatureFlags {
return getBoolean(SENDER_KEY, false);
}
/** A comma-delimited list of country codes that should not be told about SMS during onboarding. */
public static @NonNull String suggestSmsBlacklist() {
return getString(SUGGEST_SMS_BLACKLIST, "");
}
/** Only for rendering debug info. */
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
return new TreeMap<>(REMOTE_VALUES);

View File

@@ -8,11 +8,15 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.mms.PushMediaConstraints;
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
import org.thoughtcrime.securesms.recipients.Recipient;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
/**
* Provide access to locale specific values within feature flags following the locale CSV-Colon format.
@@ -47,6 +51,16 @@ public final class LocaleFeatureFlags {
return Optional.ofNullable(PushMediaConstraints.MediaConfig.forLevel(level));
}
/**
* Whether or not you should suggest SMS during onboarding.
*/
public static boolean shouldSuggestSms() {
Set<String> blacklist = new HashSet<>(Arrays.asList(FeatureFlags.suggestSmsBlacklist().split(",")));
String countryCode = String.valueOf(PhoneNumberFormatter.getLocalCountryCode());
return !blacklist.contains(countryCode);
}
/**
* Parses a comma-separated list of country codes colon-separated from how many buckets out of 1 million
* should be enabled to see this megaphone in that country code. At the end of the list, an optional