Skip to content

Commit

Permalink
Add support for remote feature flags.
Browse files Browse the repository at this point in the history
  • Loading branch information
greyson-signal committed Jan 27, 2020
1 parent b8602ee commit 55e9f87
Show file tree
Hide file tree
Showing 33 changed files with 403 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.logging.AndroidLogger;
import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger;
import org.thoughtcrime.securesms.logging.Log;
Expand All @@ -71,6 +72,7 @@
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
import org.thoughtcrime.securesms.service.UpdateApkRefreshListener;
import org.thoughtcrime.securesms.stickers.BlessedPacks;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
Expand Down Expand Up @@ -133,6 +135,7 @@ public void onCreate() {
initializeBlobProvider();
initializeCleanup();
initializeCameraX();
FeatureFlags.init();
NotificationChannels.create(this);
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ThemeUtil;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public String[] getRecipientStrings() {
}

private String getRecipientName(Recipient recipient) {
if (FeatureFlags.PROFILE_DISPLAY) return recipient.getDisplayName(context);
if (FeatureFlags.profileDisplay()) return recipient.getDisplayName(context);

String name = recipient.toShortString(context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ private void setSummaries(Recipient recipient) {
colorPreference.setColors(MaterialColors.CONVERSATION_PALETTE.asConversationColorArray(requireActivity()));
colorPreference.setColor(recipient.getColor().toActionBarColor(requireActivity()));

if (FeatureFlags.PROFILE_DISPLAY) {
if (FeatureFlags.profileDisplay()) {
aboutPreference.setTitle(recipient.getDisplayName(requireContext()));
aboutPreference.setSummary(recipient.resolve().getE164().or(""));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public void onCreate(Bundle bundle) {
byte[] localId;
byte[] remoteId;

if (FeatureFlags.UUIDS && recipient.resolve().getUuid().isPresent()) {
if (FeatureFlags.uuids() && recipient.resolve().getUuid().isPresent()) {
Log.i(TAG, "Using UUID (version 2).");
version = 2;
localId = UuidUtil.toByteArray(TextSecurePreferences.getLocalUuid(requireContext()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void setText(Recipient recipient, boolean read, @Nullable String suffix)

if (recipient.isLocalNumber()) {
builder.append(getContext().getString(R.string.note_to_self));
} else if (!FeatureFlags.PROFILE_DISPLAY && recipient.getName(getContext()) == null && !recipient.getProfileName().isEmpty()) {
} else if (!FeatureFlags.profileDisplay() && recipient.getName(getContext()) == null && !recipient.getProfileName().isEmpty()) {
SpannableString profileName = new SpannableString(" (~" + recipient.getProfileName().toString() + ") ");
profileName.setSpan(new CenterAlignedRelativeSizeSpan(0.75f), 0, profileName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
profileName.setSpan(new TypefaceSpan("sans-serif-light"), 0, profileName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ private void setPersonInfo(final @NonNull Recipient recipient) {
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(this.photo);

if (FeatureFlags.PROFILE_DISPLAY) {
if (FeatureFlags.profileDisplay()) {
this.name.setText(recipient.getDisplayName(getContext()));

if (recipient.getE164().isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,15 @@ private List<Cursor> getFilteredResults() {
cursorList.addAll(getContactsCursors());
}

if (FeatureFlags.USERNAMES && NumberUtil.isVisuallyValidNumberOrEmail(filter)) {
if (FeatureFlags.usernames() && NumberUtil.isVisuallyValidNumberOrEmail(filter)) {
cursorList.add(getPhoneNumberSearchHeaderCursor());
cursorList.add(getNewNumberCursor());
} else if (!FeatureFlags.USERNAMES && NumberUtil.isValidSmsOrEmail(filter)){
} else if (!FeatureFlags.usernames() && NumberUtil.isValidSmsOrEmail(filter)){
cursorList.add(getContactsHeaderCursor());
cursorList.add(getNewNumberCursor());
}

if (FeatureFlags.USERNAMES && UsernameUtil.isValidUsernameForSearch(filter)) {
if (FeatureFlags.usernames() && UsernameUtil.isValidUsernameForSearch(filter)) {
cursorList.add(getUsernameSearchHeaderCursor());
cursorList.add(getUsernameSearchCursor());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ public class DirectoryHelper {

@WorkerThread
public static void refreshDirectory(@NonNull Context context, boolean notifyOfNewUsers) throws IOException {
if (FeatureFlags.UUIDS) {
if (FeatureFlags.uuids()) {
// TODO [greyson] Create a DirectoryHelperV2 when appropriate.
DirectoryHelperV1.refreshDirectory(context, notifyOfNewUsers);
} else {
DirectoryHelperV1.refreshDirectory(context, notifyOfNewUsers);
}

if (FeatureFlags.STORAGE_SERVICE) {
if (FeatureFlags.storageService()) {
ApplicationDependencies.getJobManager().add(new StorageSyncJob());
}
}
Expand All @@ -34,14 +34,14 @@ public static RegisteredState refreshDirectoryFor(@NonNull Context context, @Non
RegisteredState originalRegisteredState = recipient.resolve().getRegistered();
RegisteredState newRegisteredState = null;

if (FeatureFlags.UUIDS) {
if (FeatureFlags.uuids()) {
// TODO [greyson] Create a DirectoryHelperV2 when appropriate.
newRegisteredState = DirectoryHelperV1.refreshDirectoryFor(context, recipient, notifyOfNewUsers);
} else {
newRegisteredState = DirectoryHelperV1.refreshDirectoryFor(context, recipient, notifyOfNewUsers);
}

if (FeatureFlags.STORAGE_SERVICE && newRegisteredState != originalRegisteredState) {
if (FeatureFlags.storageService() && newRegisteredState != originalRegisteredState) {
ApplicationDependencies.getJobManager().add(new StorageSyncJob());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2014,7 +2014,7 @@ private void setBlockedUserState(Recipient recipient, boolean isSecureText, bool
}

private void setGroupShareProfileReminder(@NonNull Recipient recipient) {
if (!FeatureFlags.MESSAGE_REQUESTS && recipient.isPushGroup() && !recipient.isProfileSharing()) {
if (!FeatureFlags.messageRequests() && recipient.isPushGroup() && !recipient.isProfileSharing()) {
groupShareProfileView.get().setRecipient(recipient);
groupShareProfileView.get().setVisibility(View.VISIBLE);
} else if (groupShareProfileView.resolved()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ public void onLoadFinished(@NonNull Loader<Cursor> cursorLoader, Cursor cursor)
setLastSeen(loader.getLastSeen());
}

if (FeatureFlags.MESSAGE_REQUESTS) {
if (FeatureFlags.messageRequests()) {
if (!loader.hasSent() && !recipient.get().isSystemContact() && !recipient.get().isProfileSharing() && !recipient.get().isBlocked() && recipient.get().isRegistered()) {
listener.onMessageRequest();
} else {
Expand Down Expand Up @@ -994,8 +994,8 @@ public void onItemLongClick(View maskTarget, MessageRecord messageRecord) {

if (actionMode != null) return;

if (FeatureFlags.REACTION_SENDING &&
messageRecord.isSecure() &&
if (FeatureFlags.reactionSending() &&
messageRecord.isSecure() &&
((ConversationAdapter) list.getAdapter()).getSelectedItems().isEmpty())
{
isReacting = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ private boolean shouldInterceptClicks(MessageRecord messageRecord) {
private void setGroupMessageStatus(MessageRecord messageRecord, Recipient recipient) {
if (groupThread && !messageRecord.isOutgoing()) {

if (FeatureFlags.PROFILE_DISPLAY) {
if (FeatureFlags.profileDisplay()) {
this.groupSender.setText(recipient.getDisplayName(getContext()));
this.groupSenderProfileName.setVisibility(View.GONE);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private void setComposeTitle() {
}

private void setRecipientTitle(Recipient recipient) {
if (FeatureFlags.PROFILE_DISPLAY) {
if (FeatureFlags.profileDisplay()) {
if (recipient.isGroup()) setGroupRecipientTitle(recipient);
else if (recipient.isLocalNumber()) setSelfTitle();
else setIndividualRecipientTitle(recipient);
Expand Down Expand Up @@ -166,7 +166,7 @@ private void setContactRecipientTitle(Recipient recipient) {
private void setGroupRecipientTitle(Recipient recipient) {
String localNumber = TextSecurePreferences.getLocalNumber(getContext());

if (FeatureFlags.PROFILE_DISPLAY) {
if (FeatureFlags.profileDisplay()) {
this.title.setText(recipient.getDisplayName(getContext()));
} else {
this.title.setText(recipient.getName(getContext()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ public void clearDirtyState(@NonNull List<RecipientId> recipients) {
}

void markDirty(@NonNull RecipientId recipientId, @NonNull DirtyState dirtyState) {
if (!FeatureFlags.STORAGE_SERVICE) return;
if (!FeatureFlags.storageService()) return;

ContentValues contentValues = new ContentValues(1);
contentValues.put(DIRTY, dirtyState.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static synchronized void init(@NonNull Application application, @NonNull
}

public static synchronized @NonNull KeyBackupService getKeyBackupService() {
if (!FeatureFlags.KBS) throw new AssertionError();
if (!FeatureFlags.kbs()) throw new AssertionError();
return getSignalServiceAccountManager().getKeyBackupService(IasKeyStore.getIasKeyStore(application),
BuildConfig.KEY_BACKUP_ENCLAVE_NAME,
BuildConfig.KEY_BACKUP_MRENCLAVE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public static Map<String, Job.Factory> getJobFactories(@NonNull Application appl
put(RefreshAttributesJob.KEY, new RefreshAttributesJob.Factory());
put(RefreshOwnProfileJob.KEY, new RefreshOwnProfileJob.Factory());
put(RefreshPreKeysJob.KEY, new RefreshPreKeysJob.Factory());
put(RemoteConfigRefreshJob.KEY, new RemoteConfigRefreshJob.Factory());
put(RequestGroupInfoJob.KEY, new RequestGroupInfoJob.Factory());
put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory());
put(RetrieveProfileJob.KEY, new RetrieveProfileJob.Factory());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.thoughtcrime.securesms.jobs;

import androidx.annotation.NonNull;

import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class RemoteConfigRefreshJob extends BaseJob {

public static final String KEY = "RemoteConfigRefreshJob";

public RemoteConfigRefreshJob() {
this(new Job.Parameters.Builder()
.setQueue("RemoteConfigRefreshJob")
.setMaxInstances(1)
.setMaxAttempts(Parameters.UNLIMITED)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.build());
}

private RemoteConfigRefreshJob(@NonNull Parameters parameters) {
super(parameters);
}

@Override
public @NonNull Data serialize() {
return Data.EMPTY;
}

@Override
public @NonNull String getFactoryKey() {
return KEY;
}

@Override
protected void onRun() throws Exception {
Map<String, Boolean> config = ApplicationDependencies.getSignalServiceAccountManager().getRemoteConfig();
FeatureFlags.updateDiskCache(config);
SignalStore.setRemoteConfigLastFetchTime(System.currentTimeMillis());
}

@Override
protected boolean onShouldRetry(@NonNull Exception e) {
return e instanceof PushNetworkException;
}

@Override
public void onFailure() {
}

public static final class Factory implements Job.Factory<RemoteConfigRefreshJob> {
@Override
public @NonNull RemoteConfigRefreshJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RemoteConfigRefreshJob(parameters);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private void handlePhoneNumberRecipient(Recipient recipient) throws IOException

setProfileName(recipient, profile.getName());
setProfileAvatar(recipient, profile.getAvatar());
if (FeatureFlags.USERNAMES) setUsername(recipient, profile.getUsername());
if (FeatureFlags.usernames()) setUsername(recipient, profile.getUsername());
setProfileCapabilities(recipient, profile.getCapabilities());
setIdentityKey(recipient, profile.getIdentityKey());
setUnidentifiedAccessMode(recipient, profile.getUnidentifiedAccess(), profile.isUnrestrictedUnidentifiedAccess());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private StorageForcePushJob(@NonNull Parameters parameters) {

@Override
protected void onRun() throws IOException, RetryLaterException {
if (!FeatureFlags.STORAGE_SERVICE) throw new AssertionError();
if (!FeatureFlags.storageService()) throw new AssertionError();

MasterKey kbsMasterKey = SignalStore.kbsValues().getPinBackedMasterKey();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private StorageSyncJob(@NonNull Parameters parameters) {

@Override
protected void onRun() throws IOException, RetryLaterException {
if (!FeatureFlags.STORAGE_SERVICE) throw new AssertionError();
if (!FeatureFlags.storageService()) throw new AssertionError();

try {
boolean needsMultiDeviceSync = performSync();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.keyvalue;

import android.content.Context;

import androidx.annotation.NonNull;

import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
Expand All @@ -10,12 +12,32 @@
*/
public final class SignalStore {

private static final String REMOTE_CONFIG = "remote_config";
private static final String REMOTE_CONFIG_LAST_FETCH_TIME = "remote_config_last_fetch_time";

private SignalStore() {}

public static KbsValues kbsValues() {
return new KbsValues(getStore());
}

public static String getRemoteConfig() {
return getStore().getString(REMOTE_CONFIG, null);
}

public static void setRemoteConfig(String value) {
putString(REMOTE_CONFIG, value);
}

public static long getRemoteConfigLastFetchTime() {
return getStore().getLong(REMOTE_CONFIG_LAST_FETCH_TIME, 0);
}

public static void setRemoteConfigLastFetchTime(long time) {
putLong(REMOTE_CONFIG_LAST_FETCH_TIME, time);
}


/**
* Ensures any pending writes are finished. Only intended to be called by
* {@link SignalUncaughtExceptionHandler}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private static TextWatcher getV1PinWatcher(@NonNull Context context, AlertDialog
dialog.dismiss();
RegistrationLockReminders.scheduleReminder(context, true);

if (FeatureFlags.KBS) {
if (FeatureFlags.kbs()) {
Log.i(TAG, "Pin V1 successfully remembered, scheduling a migration to V2");
ApplicationDependencies.getJobManager().add(new RegistrationPinV2MigrationJob());
}
Expand Down Expand Up @@ -201,7 +201,7 @@ protected void onPreExecute() {
@Override
protected Boolean doInBackground(Void... voids) {
try {
if (!FeatureFlags.KBS) {
if (!FeatureFlags.kbs()) {
Log.i(TAG, "Setting V1 pin");
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
accountManager.setPin(pinValue);
Expand Down Expand Up @@ -282,7 +282,7 @@ protected void onPreExecute() {
@Override
protected Boolean doInBackground(Void... voids) {
try {
if (!FeatureFlags.KBS) {
if (!FeatureFlags.kbs()) {
Log.i(TAG, "Removing v1 registration lock pin from server");
ApplicationDependencies.getSignalServiceAccountManager().removeV1Pin();
} else {
Expand Down

0 comments on commit 55e9f87

Please sign in to comment.