Remove versioned profiles feature flag.

master
Alan Evans 2020-07-07 12:00:29 -03:00 committed by Greyson Parrelli
parent 99ff0c1e3c
commit 96e888a4f5
12 changed files with 76 additions and 136 deletions

View File

@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.migrations.LegacyMigrationJob;
import org.thoughtcrime.securesms.migrations.MigrationCompleteJob;
import org.thoughtcrime.securesms.migrations.PassingMigrationJob;
import org.thoughtcrime.securesms.migrations.PinReminderMigrationJob;
import org.thoughtcrime.securesms.migrations.ProfileMigrationJob;
import org.thoughtcrime.securesms.migrations.RecipientSearchMigrationJob;
import org.thoughtcrime.securesms.migrations.RegistrationPinV2MigrationJob;
import org.thoughtcrime.securesms.migrations.StickerAdditionMigrationJob;
@ -134,6 +135,7 @@ public final class JobManagerFactories {
put(StorageCapabilityMigrationJob.KEY, new StorageCapabilityMigrationJob.Factory());
put(StorageServiceMigrationJob.KEY, new StorageServiceMigrationJob.Factory());
put(UuidMigrationJob.KEY, new UuidMigrationJob.Factory());
put(ProfileMigrationJob.KEY, new ProfileMigrationJob.Factory());
// Dead jobs
put(FailingJob.KEY, new FailingJob.Factory());

View File

@ -14,12 +14,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.profiles.ProfileName;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.ProfileUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
import org.whispersystems.signalservice.api.util.StreamDetails;
public final class ProfileUploadJob extends BaseJob {
@ -52,15 +47,10 @@ public final class ProfileUploadJob extends BaseJob {
protected void onRun() throws Exception {
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
ProfileName profileName = Recipient.self().getProfileName();
String avatarPath = null;
String avatarPath;
try (StreamDetails avatar = AvatarHelper.getSelfProfileAvatarStream(context)) {
if (FeatureFlags.versionedProfiles()) {
avatarPath = accountManager.setVersionedProfile(Recipient.self().getUuid().get(), profileKey, profileName.serialize(), avatar).orNull();
} else {
accountManager.setProfileName(profileKey, profileName.serialize());
avatarPath = accountManager.setProfileAvatar(profileKey, avatar).orNull();
}
avatarPath = accountManager.setVersionedProfile(Recipient.self().getUuid().get(), profileKey, profileName.serialize(), avatar).orNull();
}
DatabaseFactory.getRecipientDatabase(context).setProfileAvatar(Recipient.self().getId(), avatarPath);
@ -85,11 +75,10 @@ public final class ProfileUploadJob extends BaseJob {
public void onFailure() {
}
public static class Factory implements Job.Factory {
public static class Factory implements Job.Factory<ProfileUploadJob> {
@NonNull
@Override
public Job create(@NonNull Parameters parameters, @NonNull Data data) {
public @NonNull ProfileUploadJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new ProfileUploadJob(parameters);
}
}

View File

@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.profiles.ProfileName;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.ProfileUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.util.guava.Optional;
@ -93,7 +92,7 @@ public class RefreshOwnProfileJob extends BaseJob {
}
private static SignalServiceProfile.RequestType getRequestType(@NonNull Recipient recipient) {
return FeatureFlags.versionedProfiles() && !recipient.hasProfileKeyCredential()
return !recipient.hasProfileKeyCredential()
? SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL
: SignalServiceProfile.RequestType.PROFILE;
}

View File

@ -307,7 +307,7 @@ public class RetrieveProfileJob extends BaseJob {
}
private static SignalServiceProfile.RequestType getRequestType(@NonNull Recipient recipient) {
return FeatureFlags.versionedProfiles() && !recipient.hasProfileKeyCredential()
return !recipient.hasProfileKeyCredential()
? SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL
: SignalServiceProfile.RequestType.PROFILE;
}

View File

@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.util.StreamDetails;
@ -57,16 +56,11 @@ public class RotateProfileKeyJob extends BaseJob {
recipientDatabase.setProfileKey(self.getId(), profileKey);
try (StreamDetails avatarStream = AvatarHelper.getSelfProfileAvatarStream(context)) {
if (FeatureFlags.versionedProfiles()) {
accountManager.setVersionedProfile(self.getUuid().get(),
profileKey,
Recipient.self().getProfileName().serialize(),
avatarStream);
} else {
accountManager.setProfileName(profileKey, Recipient.self().getProfileName().serialize());
accountManager.setProfileAvatar(profileKey, avatarStream);
}
}
accountManager.setVersionedProfile(self.getUuid().get(),
profileKey,
Recipient.self().getProfileName().serialize(),
avatarStream);
}
ApplicationDependencies.getJobManager().add(new RefreshAttributesJob());

View File

@ -39,7 +39,7 @@ public class ApplicationMigrations {
private static final int LEGACY_CANONICAL_VERSION = 455;
public static final int CURRENT_VERSION = 15;
public static final int CURRENT_VERSION = 16;
private static final class Version {
static final int LEGACY = 1;
@ -53,10 +53,11 @@ public class ApplicationMigrations {
//static final int TEST_ARGON2 = 9;
static final int SWOON_STICKERS = 10;
static final int STORAGE_SERVICE = 11;
static final int STORAGE_KEY_ROTATE = 12;
//static final int STORAGE_KEY_ROTATE = 12;
static final int REMOVE_AVATAR_ID = 13;
static final int STORAGE_CAPABILITY = 14;
static final int PIN_REMINDER = 15;
static final int VERSIONED_PROFILE = 16;
}
/**
@ -231,6 +232,10 @@ public class ApplicationMigrations {
jobs.put(Version.PIN_REMINDER, new PinReminderMigrationJob());
}
if (lastSeenVersion < Version.VERSIONED_PROFILE) {
jobs.put(Version.VERSIONED_PROFILE, new ProfileMigrationJob());
}
return jobs;
}

View File

@ -0,0 +1,55 @@
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.logging.Log;
/**
* Schedules a re-upload of the users profile.
*/
public final class ProfileMigrationJob extends MigrationJob {
private static final String TAG = Log.tag(ProfileMigrationJob.class);
public static final String KEY = "ProfileMigrationJob";
ProfileMigrationJob() {
this(new Parameters.Builder().build());
}
private ProfileMigrationJob(@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 profile upload job");
ApplicationDependencies.getJobManager().add(new ProfileUploadJob());
}
@Override
boolean shouldRetry(@NonNull Exception e) {
return false;
}
public static class Factory implements Job.Factory<ProfileMigrationJob> {
@Override
public @NonNull ProfileMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new ProfileMigrationJob(parameters);
}
}
}

View File

@ -11,7 +11,6 @@ import com.google.android.collect.Sets;
import org.json.JSONException;
import org.json.JSONObject;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobs.ProfileUploadJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob;
import org.thoughtcrime.securesms.jobs.RemoteConfigRefreshJob;
@ -55,8 +54,6 @@ public final class FeatureFlags {
private static final String REMOTE_DELETE = "android.remoteDelete";
private static final String PROFILE_FOR_CALLING = "android.profileForCalling.2";
private static final String CALLING_PIP = "android.callingPip";
private static final String VERSIONED_PROFILES_1 = "android.versionedProfiles";
private static final String VERSIONED_PROFILES_2 = "android.versionedProfiles.2";
private static final String GROUPS_V2 = "android.groupsv2";
private static final String GROUPS_V2_CREATE = "android.groupsv2.create";
private static final String GROUPS_V2_CAPACITY = "android.groupsv2.capacity";
@ -73,8 +70,6 @@ public final class FeatureFlags {
REMOTE_DELETE,
PROFILE_FOR_CALLING,
CALLING_PIP,
VERSIONED_PROFILES_1,
VERSIONED_PROFILES_2,
GROUPS_V2,
GROUPS_V2_CREATE,
GROUPS_V2_CAPACITY,
@ -106,8 +101,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<String> STICKY = Sets.newHashSet(
VERSIONED_PROFILES_1,
VERSIONED_PROFILES_2,
GROUPS_V2
);
@ -123,11 +116,6 @@ public final class FeatureFlags {
* desired test state.
*/
private static final Map<String, OnFlagChange> FLAG_CHANGE_LISTENERS = new HashMap<String, OnFlagChange>() {{
put(VERSIONED_PROFILES_2, (change) -> {
if (change == Change.ENABLED) {
ApplicationDependencies.getJobManager().add(new ProfileUploadJob());
}
});
put(GROUPS_V2, (change) -> {
if (change == Change.ENABLED) {
ApplicationDependencies.getJobManager().startChain(new RefreshAttributesJob())
@ -214,15 +202,9 @@ public final class FeatureFlags {
return getBoolean(CALLING_PIP, false);
}
/** Read and write versioned profile information. */
public static boolean versionedProfiles() {
return getBoolean(VERSIONED_PROFILES_1, false) ||
getBoolean(VERSIONED_PROFILES_2, false);
}
/** Groups v2 send and receive. */
public static boolean groupsV2() {
return versionedProfiles() && getBoolean(GROUPS_V2, false);
return getBoolean(GROUPS_V2, false);
}
/** Groups v2 send and receive. */

View File

@ -1,11 +0,0 @@
package org.whispersystems.signalservice;
/**
* A location for constants that allows us to turn features on and off at the service level during development.
* After a feature has been launched, the flag should be removed.
*/
public final class FeatureFlags {
/** Prevent usage of non-versioned profile endpoints. */
public static final boolean DISALLOW_OLD_PROFILE_SETTING = false;
}

View File

@ -20,7 +20,6 @@ import org.whispersystems.libsignal.logging.Log;
import org.whispersystems.libsignal.state.PreKeyRecord;
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.FeatureFlags;
import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException;
import org.whispersystems.signalservice.api.crypto.ProfileCipher;
import org.whispersystems.signalservice.api.crypto.ProfileCipherOutputStream;
@ -629,39 +628,6 @@ public class SignalServiceAccountManager {
return this.pushServiceSocket.getTurnServerInfo();
}
public void setProfileName(ProfileKey key, String name)
throws IOException
{
if (FeatureFlags.DISALLOW_OLD_PROFILE_SETTING) {
throw new AssertionError();
}
if (name == null) name = "";
String ciphertextName = Base64.encodeBytesWithoutPadding(new ProfileCipher(key).encryptName(name.getBytes(StandardCharsets.UTF_8), ProfileCipher.NAME_PADDED_LENGTH));
this.pushServiceSocket.setProfileName(ciphertextName);
}
public Optional<String> setProfileAvatar(ProfileKey key, StreamDetails avatar)
throws IOException
{
if (FeatureFlags.DISALLOW_OLD_PROFILE_SETTING) {
throw new AssertionError();
}
ProfileAvatarData profileAvatarData = null;
if (avatar != null) {
profileAvatarData = new ProfileAvatarData(avatar.getStream(),
ProfileCipherOutputStream.getCiphertextLength(avatar.getLength()),
avatar.getContentType(),
new ProfileCipherOutputStreamFactory(key));
}
return this.pushServiceSocket.setProfileAvatar(profileAvatarData);
}
/**
* @return The avatar URL path, if one was written.
*/

View File

@ -10,7 +10,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.signal.zkgroup.InvalidInputException;
import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse;
import org.whispersystems.libsignal.logging.Log;
import org.whispersystems.signalservice.FeatureFlags;
import org.whispersystems.signalservice.internal.util.JsonUtil;
import java.util.UUID;

View File

@ -31,7 +31,6 @@ import org.whispersystems.libsignal.state.PreKeyRecord;
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.libsignal.util.Pair;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.FeatureFlags;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.groupsv2.CredentialResponse;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString;
@ -691,45 +690,6 @@ public class PushServiceSocket {
}
}
public void setProfileName(String name) throws NonSuccessfulResponseCodeException, PushNetworkException {
if (FeatureFlags.DISALLOW_OLD_PROFILE_SETTING) {
throw new AssertionError();
}
makeServiceRequest(String.format(PROFILE_PATH, "name/" + (name == null ? "" : URLEncoder.encode(name))), "PUT", "");
}
public Optional<String> setProfileAvatar(ProfileAvatarData profileAvatar)
throws NonSuccessfulResponseCodeException, PushNetworkException
{
if (FeatureFlags.DISALLOW_OLD_PROFILE_SETTING) {
throw new AssertionError();
}
String response = makeServiceRequest(String.format(PROFILE_PATH, "form/avatar"), "GET", null);
ProfileAvatarUploadAttributes formAttributes;
try {
formAttributes = JsonUtil.fromJson(response, ProfileAvatarUploadAttributes.class);
} catch (IOException e) {
Log.w(TAG, e);
throw new NonSuccessfulResponseCodeException("Unable to parse entity");
}
if (profileAvatar != null) {
uploadToCdn0(AVATAR_UPLOAD_PATH, formAttributes.getAcl(), formAttributes.getKey(),
formAttributes.getPolicy(), formAttributes.getAlgorithm(),
formAttributes.getCredential(), formAttributes.getDate(),
formAttributes.getSignature(), profileAvatar.getData(),
profileAvatar.getContentType(), profileAvatar.getDataLength(),
profileAvatar.getOutputStreamFactory(), null, null);
return Optional.of(formAttributes.getKey());
}
return Optional.absent();
}
/**
* @return The avatar URL path, if one was written.
*/