mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-26 22:20:20 +00:00
Only upload your avatar if it's being changed.
New server param means we don't have to upload the avatar if we want to keep it the same.
This commit is contained in:
committed by
Cody Henthorne
parent
87ad4be117
commit
b45740884b
@@ -6,20 +6,15 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.thoughtcrime.securesms.badges.models.Badge;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobs.GroupV2UpdateSelfProfileKeyJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceProfileKeyUpdateJob;
|
||||
@@ -44,12 +39,12 @@ import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException;
|
||||
import org.whispersystems.signalservice.api.crypto.ProfileCipher;
|
||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
|
||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
||||
import org.whispersystems.signalservice.api.profiles.AvatarUploadParams;
|
||||
import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.services.ProfileService;
|
||||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
|
||||
@@ -226,14 +221,12 @@ public final class ProfileUtil {
|
||||
*/
|
||||
public static void uploadProfileWithBadges(@NonNull Context context, @NonNull List<Badge> badges) throws IOException {
|
||||
Log.d(TAG, "uploadProfileWithBadges()");
|
||||
try (StreamDetails avatar = AvatarHelper.getSelfProfileAvatarStream(context)) {
|
||||
uploadProfile(Recipient.self().getProfileName(),
|
||||
Optional.fromNullable(Recipient.self().getAbout()).or(""),
|
||||
Optional.fromNullable(Recipient.self().getAboutEmoji()).or(""),
|
||||
getSelfPaymentsAddressProtobuf(),
|
||||
avatar,
|
||||
badges);
|
||||
}
|
||||
uploadProfile(Recipient.self().getProfileName(),
|
||||
Optional.fromNullable(Recipient.self().getAbout()).or(""),
|
||||
Optional.fromNullable(Recipient.self().getAboutEmoji()).or(""),
|
||||
getSelfPaymentsAddressProtobuf(),
|
||||
AvatarUploadParams.unchanged(AvatarHelper.hasAvatar(context, Recipient.self().getId())),
|
||||
badges);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,7 +241,7 @@ public final class ProfileUtil {
|
||||
Optional.fromNullable(Recipient.self().getAbout()).or(""),
|
||||
Optional.fromNullable(Recipient.self().getAboutEmoji()).or(""),
|
||||
getSelfPaymentsAddressProtobuf(),
|
||||
avatar,
|
||||
AvatarUploadParams.unchanged(AvatarHelper.hasAvatar(context, Recipient.self().getId())),
|
||||
Recipient.self().getBadges());
|
||||
}
|
||||
}
|
||||
@@ -265,7 +258,7 @@ public final class ProfileUtil {
|
||||
about,
|
||||
emoji,
|
||||
getSelfPaymentsAddressProtobuf(),
|
||||
avatar,
|
||||
AvatarUploadParams.unchanged(AvatarHelper.hasAvatar(context, Recipient.self().getId())),
|
||||
Recipient.self().getBadges());
|
||||
}
|
||||
}
|
||||
@@ -291,7 +284,7 @@ public final class ProfileUtil {
|
||||
Optional.fromNullable(Recipient.self().getAbout()).or(""),
|
||||
Optional.fromNullable(Recipient.self().getAboutEmoji()).or(""),
|
||||
getSelfPaymentsAddressProtobuf(),
|
||||
avatar,
|
||||
AvatarUploadParams.forAvatar(avatar),
|
||||
Recipient.self().getBadges());
|
||||
}
|
||||
|
||||
@@ -299,7 +292,7 @@ public final class ProfileUtil {
|
||||
@Nullable String about,
|
||||
@Nullable String aboutEmoji,
|
||||
@Nullable SignalServiceProtos.PaymentAddress paymentsAddress,
|
||||
@Nullable StreamDetails avatar,
|
||||
@NonNull AvatarUploadParams avatar,
|
||||
@NonNull List<Badge> badges)
|
||||
throws IOException
|
||||
{
|
||||
@@ -312,8 +305,13 @@ public final class ProfileUtil {
|
||||
Log.d(TAG, "Uploading " + (!Util.isEmpty(about) ? "non-" : "") + "empty about.");
|
||||
Log.d(TAG, "Uploading " + (!Util.isEmpty(aboutEmoji) ? "non-" : "") + "empty emoji.");
|
||||
Log.d(TAG, "Uploading " + (paymentsAddress != null ? "non-" : "") + "empty payments address.");
|
||||
Log.d(TAG, "Uploading " + (avatar != null && avatar.getLength() != 0 ? "non-" : "") + "empty avatar.");
|
||||
Log.d(TAG, "Uploading " + ((!badgeIds.isEmpty()) ? "non-" : "") + "empty badge list");
|
||||
Log.d(TAG, "Uploading " + ((!badgeIds.isEmpty()) ? "non-" : "") + "empty badge list.");
|
||||
|
||||
if (avatar.keepTheSame) {
|
||||
Log.d(TAG, "Leaving avatar unchanged. We think we " + (avatar.hasAvatar ? "" : "do not ") + "have one.");
|
||||
} else {
|
||||
Log.d(TAG, "Uploading " + (avatar.stream != null && avatar.stream.getLength() != 0 ? "non-" : "") + "empty avatar.");
|
||||
}
|
||||
|
||||
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
@@ -326,7 +324,9 @@ public final class ProfileUtil {
|
||||
avatar,
|
||||
badgeIds).orNull();
|
||||
SignalStore.registrationValues().markHasUploadedProfile();
|
||||
SignalDatabase.recipients().setProfileAvatar(Recipient.self().getId(), avatarPath);
|
||||
if (!avatar.keepTheSame) {
|
||||
SignalDatabase.recipients().setProfileAvatar(Recipient.self().getId(), avatarPath);
|
||||
}
|
||||
ApplicationDependencies.getJobManager().add(new RefreshOwnProfileJob());
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.whispersystems.signalservice.api.messages.calls.TurnServerInfo;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.DeviceInfo;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.VerifyDeviceResponse;
|
||||
import org.whispersystems.signalservice.api.payments.CurrencyConversions;
|
||||
import org.whispersystems.signalservice.api.profiles.AvatarUploadParams;
|
||||
import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfileWrite;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
@@ -53,7 +54,6 @@ import org.whispersystems.signalservice.api.storage.StorageId;
|
||||
import org.whispersystems.signalservice.api.storage.StorageKey;
|
||||
import org.whispersystems.signalservice.api.storage.StorageManifestKey;
|
||||
import org.whispersystems.signalservice.api.util.CredentialsProvider;
|
||||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
|
||||
import org.whispersystems.signalservice.internal.contacts.crypto.ContactDiscoveryCipher;
|
||||
@@ -811,7 +811,7 @@ public class SignalServiceAccountManager {
|
||||
String about,
|
||||
String aboutEmoji,
|
||||
Optional<SignalServiceProtos.PaymentAddress> paymentsAddress,
|
||||
StreamDetails avatar,
|
||||
AvatarUploadParams avatar,
|
||||
List<String> visibleBadgeIds)
|
||||
throws IOException
|
||||
{
|
||||
@@ -822,13 +822,12 @@ public class SignalServiceAccountManager {
|
||||
byte[] ciphertextAbout = profileCipher.encryptString(about, ProfileCipher.getTargetAboutLength(about));
|
||||
byte[] ciphertextEmoji = profileCipher.encryptString(aboutEmoji, ProfileCipher.EMOJI_PADDED_LENGTH);
|
||||
byte[] ciphertextMobileCoinAddress = paymentsAddress.transform(address -> profileCipher.encryptWithLength(address.toByteArray(), ProfileCipher.PAYMENTS_ADDRESS_CONTENT_SIZE)).orNull();
|
||||
boolean hasAvatar = avatar != null;
|
||||
ProfileAvatarData profileAvatarData = null;
|
||||
|
||||
if (hasAvatar) {
|
||||
profileAvatarData = new ProfileAvatarData(avatar.getStream(),
|
||||
ProfileCipherOutputStream.getCiphertextLength(avatar.getLength()),
|
||||
avatar.getContentType(),
|
||||
if (avatar.stream != null && !avatar.keepTheSame) {
|
||||
profileAvatarData = new ProfileAvatarData(avatar.stream.getStream(),
|
||||
ProfileCipherOutputStream.getCiphertextLength(avatar.stream.getLength()),
|
||||
avatar.stream.getContentType(),
|
||||
new ProfileCipherOutputStreamFactory(profileKey));
|
||||
}
|
||||
|
||||
@@ -837,7 +836,8 @@ public class SignalServiceAccountManager {
|
||||
ciphertextAbout,
|
||||
ciphertextEmoji,
|
||||
ciphertextMobileCoinAddress,
|
||||
hasAvatar,
|
||||
avatar.hasAvatar,
|
||||
avatar.keepTheSame,
|
||||
profileKey.getCommitment(aci.uuid()).serialize(),
|
||||
visibleBadgeIds),
|
||||
profileAvatarData);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.whispersystems.signalservice.api.profiles;
|
||||
|
||||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||
|
||||
/**
|
||||
* A model to represent the attributes of an avatar upload.
|
||||
*/
|
||||
public class AvatarUploadParams {
|
||||
/** Whether or not you should keep the avatar the same on the server. */
|
||||
public final boolean keepTheSame;
|
||||
|
||||
/** Whether or not you want an avatar. */
|
||||
public final boolean hasAvatar;
|
||||
|
||||
/** A stream representing the content of the avatar to be uploaded. */
|
||||
public final StreamDetails stream;
|
||||
|
||||
/**
|
||||
* Indicates that you want to leave the avatar as it already is on the server.
|
||||
* @param hasAvatar Whether or not you have an avatar. If true, the avatar you have on the server will remain as it is.
|
||||
* If this is false, it *will* delete the avatar. Weird to have this with the 'unchanged' bit, I know,
|
||||
* but this boolean already existed before we added the 'keepTheSame' functionality, so we gotta deal
|
||||
* with it.
|
||||
*/
|
||||
public static AvatarUploadParams unchanged(boolean hasAvatar) {
|
||||
return new AvatarUploadParams(true, hasAvatar, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that you'd like set the contents of this stream as your avatar. If null, the avatar will be removed.
|
||||
*/
|
||||
public static AvatarUploadParams forAvatar(StreamDetails avatarStream) {
|
||||
return new AvatarUploadParams(false, avatarStream != null, avatarStream);
|
||||
}
|
||||
|
||||
private AvatarUploadParams(boolean keepTheSame, boolean hasAvatar, StreamDetails stream) {
|
||||
this.keepTheSame = keepTheSame;
|
||||
this.hasAvatar = hasAvatar;
|
||||
this.stream = stream;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,9 @@ public class SignalServiceProfileWrite {
|
||||
@JsonProperty
|
||||
private boolean avatar;
|
||||
|
||||
@JsonProperty
|
||||
private boolean sameAvatar;
|
||||
|
||||
@JsonProperty
|
||||
private byte[] commitment;
|
||||
|
||||
@@ -35,13 +38,14 @@ public class SignalServiceProfileWrite {
|
||||
public SignalServiceProfileWrite(){
|
||||
}
|
||||
|
||||
public SignalServiceProfileWrite(String version, byte[] name, byte[] about, byte[] aboutEmoji, byte[] paymentAddress, boolean avatar, byte[] commitment, List<String> badgeIds) {
|
||||
public SignalServiceProfileWrite(String version, byte[] name, byte[] about, byte[] aboutEmoji, byte[] paymentAddress, boolean hasAvatar, boolean sameAvatar, byte[] commitment, List<String> badgeIds) {
|
||||
this.version = version;
|
||||
this.name = name;
|
||||
this.about = about;
|
||||
this.aboutEmoji = aboutEmoji;
|
||||
this.paymentAddress = paymentAddress;
|
||||
this.avatar = avatar;
|
||||
this.avatar = hasAvatar;
|
||||
this.sameAvatar = sameAvatar;
|
||||
this.commitment = commitment;
|
||||
this.badgeIds = badgeIds;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user