From 45915bed902f766bef1ee185df0fd417ace012e8 Mon Sep 17 00:00:00 2001 From: Alan Evans Date: Tue, 22 Sep 2020 17:31:07 -0300 Subject: [PATCH] Inline GV2 feature flag. --- .../securesms/AppCapabilities.java | 4 +- .../GroupJoinBottomSheetDialogFragment.java | 2 +- .../securesms/jobs/JobManagerFactories.java | 2 + .../securesms/jobs/PushProcessMessageJob.java | 7 --- .../migrations/ApplicationMigrations.java | 7 ++- .../migrations/AttributesMigrationJob.java | 59 +++++++++++++++++++ .../securesms/util/FeatureFlags.java | 47 +-------------- 7 files changed, 73 insertions(+), 55 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/migrations/AttributesMigrationJob.java diff --git a/app/src/main/java/org/thoughtcrime/securesms/AppCapabilities.java b/app/src/main/java/org/thoughtcrime/securesms/AppCapabilities.java index 4a14180f09..1227a4486b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/AppCapabilities.java +++ b/app/src/main/java/org/thoughtcrime/securesms/AppCapabilities.java @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.whispersystems.signalservice.api.account.AccountAttributes; public final class AppCapabilities { @@ -9,12 +8,13 @@ public final class AppCapabilities { } private static final boolean UUID_CAPABLE = false; + private static final boolean GV2_CAPABLE = true; /** * @param storageCapable Whether or not the user can use storage service. This is another way of * asking if the user has set a Signal PIN or not. */ public static AccountAttributes.Capabilities getCapabilities(boolean storageCapable) { - return new AccountAttributes.Capabilities(UUID_CAPABLE, FeatureFlags.groupsV2(), storageCapable); + return new AccountAttributes.Capabilities(UUID_CAPABLE, GV2_CAPABLE, storageCapable); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/joining/GroupJoinBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/joining/GroupJoinBottomSheetDialogFragment.java index 0b0589399a..4638708dfd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/joining/GroupJoinBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/invitesandrequests/joining/GroupJoinBottomSheetDialogFragment.java @@ -155,7 +155,7 @@ public final class GroupJoinBottomSheetDialogFragment extends BottomSheetDialogF FeatureFlags.GroupJoinStatus groupJoinStatus = FeatureFlags.clientLocalGroupJoinStatus(); if (groupJoinStatus == FeatureFlags.GroupJoinStatus.LOCAL_CAN_JOIN) { - if (!FeatureFlags.groupsV2() || Recipient.self().getGroupsV2Capability() == Recipient.Capability.NOT_SUPPORTED) { + if (Recipient.self().getGroupsV2Capability() == Recipient.Capability.NOT_SUPPORTED) { // TODO [Alan] GV2 additional copy could be presented in these cases return FeatureFlags.GroupJoinStatus.UPDATE_TO_JOIN; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index ceddbab3b8..7409d68569 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.jobmanager.migrations.RecipientIdFollowUpJobMi import org.thoughtcrime.securesms.jobmanager.migrations.RecipientIdJobMigration; import org.thoughtcrime.securesms.jobmanager.migrations.RetrieveProfileJobMigration; import org.thoughtcrime.securesms.jobmanager.migrations.SendReadReceiptsJobMigration; +import org.thoughtcrime.securesms.migrations.AttributesMigrationJob; import org.thoughtcrime.securesms.migrations.AvatarIdRemovalMigrationJob; import org.thoughtcrime.securesms.migrations.AvatarMigrationJob; import org.thoughtcrime.securesms.migrations.CachedAttachmentsMigrationJob; @@ -126,6 +127,7 @@ public final class JobManagerFactories { put(ProfileUploadJob.KEY, new ProfileUploadJob.Factory()); // Migrations + put(AttributesMigrationJob.KEY, new AttributesMigrationJob.Factory()); put(AvatarIdRemovalMigrationJob.KEY, new AvatarIdRemovalMigrationJob.Factory()); put(AvatarMigrationJob.KEY, new AvatarMigrationJob.Factory()); put(CachedAttachmentsMigrationJob.KEY, new CachedAttachmentsMigrationJob.Factory()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java index c2e004213a..080f0c6800 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java @@ -82,7 +82,6 @@ import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.stickers.StickerLocator; import org.thoughtcrime.securesms.storage.StorageSyncHelper; import org.thoughtcrime.securesms.util.Base64; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.Hex; import org.thoughtcrime.securesms.util.IdentityUtil; @@ -1822,12 +1821,6 @@ public final class PushProcessMessageJob extends BaseJob { } else if (conversation.isGroup()) { GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); Optional groupId = GroupUtil.idFromGroupContext(message.getGroupContext()); - boolean isGv2Message = message.isGroupV2Message(); - - if (isGv2Message && !FeatureFlags.groupsV2() && groupDatabase.isUnknownGroup(groupId.get())) { - Log.i(TAG, "Ignoring GV2 message for a new group by feature flag."); - return true; - } if (groupId.isPresent() && groupDatabase.isUnknownGroup(groupId.get())) { return false; diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java index fd33936073..9a2a39f4fe 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java @@ -39,7 +39,7 @@ public class ApplicationMigrations { private static final int LEGACY_CANONICAL_VERSION = 455; - public static final int CURRENT_VERSION = 19; + public static final int CURRENT_VERSION = 20; private static final class Version { static final int LEGACY = 1; @@ -61,6 +61,7 @@ public class ApplicationMigrations { static final int PIN_OPT_OUT = 17; static final int TRIM_SETTINGS = 18; static final int THUMBNAIL_CLEANUP = 19; + static final int GV2 = 20; } /** @@ -252,6 +253,10 @@ public class ApplicationMigrations { jobs.put(Version.THUMBNAIL_CLEANUP, new DatabaseMigrationJob()); } + if (lastSeenVersion < Version.GV2) { + jobs.put(Version.GV2, new AttributesMigrationJob()); + } + return jobs; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/AttributesMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/AttributesMigrationJob.java new file mode 100644 index 0000000000..92ff92818c --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/AttributesMigrationJob.java @@ -0,0 +1,59 @@ +package org.thoughtcrime.securesms.migrations; + +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.jobs.ProfileUploadJob; +import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; +import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob; +import org.thoughtcrime.securesms.logging.Log; + +/** + * Schedules a re-upload of the users attributes followed by a download of their profile. + */ +public final class AttributesMigrationJob extends MigrationJob { + + private static final String TAG = Log.tag(AttributesMigrationJob.class); + + public static final String KEY = "AttributesMigrationJob"; + + AttributesMigrationJob() { + this(new Parameters.Builder().build()); + } + + private AttributesMigrationJob(@NonNull Parameters parameters) { + super(parameters); + } + + @Override + public boolean isUiBlocking() { + return false; + } + + @Override + public @NonNull String getFactoryKey() { + return KEY; + } + + @Override + public void performMigration() { + Log.i(TAG, "Scheduling attributes upload and profile refresh job chain"); + ApplicationDependencies.getJobManager().startChain(new RefreshAttributesJob()) + .then(new RefreshOwnProfileJob()) + .enqueue(); + } + + @Override + boolean shouldRetry(@NonNull Exception e) { + return false; + } + + public static class Factory implements Job.Factory { + @Override + public @NonNull AttributesMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) { + return new AttributesMigrationJob(parameters); + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java index 0103cf2240..6aea5cda74 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -7,23 +7,15 @@ import androidx.annotation.VisibleForTesting; import com.annimon.stream.Stream; import com.google.android.collect.Sets; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber; import org.json.JSONException; import org.json.JSONObject; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; -import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob; import org.thoughtcrime.securesms.jobs.RemoteConfigRefreshJob; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.recipients.Recipient; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -57,10 +49,6 @@ public final class FeatureFlags { private static final String USERNAMES = "android.usernames"; private static final String REMOTE_DELETE = "android.remoteDelete"; - private static final String GROUPS_V2_OLD_1 = "android.groupsv2"; - private static final String GROUPS_V2_OLD_2 = "android.groupsv2.2"; - private static final String GROUPS_V2_OLD_3 = "android.groupsv2.3"; - private static final String GROUPS_V2 = "android.groupsv2.4"; private static final String GROUPS_V2_CREATE_VERSION = "android.groupsv2.createVersion"; private static final String GROUPS_V2_JOIN_VERSION = "android.groupsv2.joinVersion"; private static final String GROUPS_V2_LINKS_VERSION = "android.groupsv2.manageGroupLinksVersion"; @@ -80,7 +68,6 @@ public final class FeatureFlags { private static final Set REMOTE_CAPABLE = Sets.newHashSet( REMOTE_DELETE, - GROUPS_V2, GROUPS_V2_CREATE_VERSION, GROUPS_V2_CAPACITY, GROUPS_V2_JOIN_VERSION, @@ -123,10 +110,6 @@ public final class FeatureFlags { * Flags in this set will stay true forever once they receive a true value from a remote config. */ private static final Set STICKY = Sets.newHashSet( - GROUPS_V2, - GROUPS_V2_OLD_1, - GROUPS_V2_OLD_2, - GROUPS_V2_OLD_3, VERIFY_V2 ); @@ -142,13 +125,6 @@ public final class FeatureFlags { * desired test state. */ private static final Map FLAG_CHANGE_LISTENERS = new HashMap() {{ - put(GROUPS_V2, (change) -> { - if (change == Change.ENABLED) { - ApplicationDependencies.getJobManager().startChain(new RefreshAttributesJob()) - .then(new RefreshOwnProfileJob()) - .enqueue(); - } - }); }}; private static final Map REMOTE_VALUES = new TreeMap<>(); @@ -206,32 +182,15 @@ public final class FeatureFlags { return getBoolean(REMOTE_DELETE, false); } - /** Groups v2 send and receive. */ - public static boolean groupsV2() { - return groupsV2OlderStickyFlags() || groupsV2LatestFlag(); - } - /** Attempt groups v2 creation. */ public static boolean groupsV2create() { - return groupsV2LatestFlag() && - getVersionFlag(GROUPS_V2_CREATE_VERSION) == VersionFlag.ON && + return getVersionFlag(GROUPS_V2_CREATE_VERSION) == VersionFlag.ON && !SignalStore.internalValues().gv2DoNotCreateGv2Groups(); } /** Allow creation and managing of group links. */ public static boolean groupsV2manageGroupLinks() { - return groupsV2() && getVersionFlag(GROUPS_V2_LINKS_VERSION) == VersionFlag.ON; - } - - private static boolean groupsV2LatestFlag() { - return getBoolean(GROUPS_V2, false); - } - - /** Clients that previously saw these flags as true must continue to respect that */ - private static boolean groupsV2OlderStickyFlags() { - return getBoolean(GROUPS_V2_OLD_1, false) || - getBoolean(GROUPS_V2_OLD_2, false) || - getBoolean(GROUPS_V2_OLD_3, false); + return getVersionFlag(GROUPS_V2_LINKS_VERSION) == VersionFlag.ON; } /** @@ -278,7 +237,7 @@ public final class FeatureFlags { /** Whether or not we allow mentions send support in groups. */ public static boolean mentions() { - return groupsV2() && getBoolean(MENTIONS, false); + return getBoolean(MENTIONS, false); } /** Whether or not to use the UUID in verification codes. */