mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-07-04 13:05:19 +01:00
Strongly type UUIDs as ACIs.
This commit is contained in:
@@ -26,7 +26,6 @@ import android.database.Cursor;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -572,7 +571,7 @@ public final class ContactSelectionListFragment extends LoggingFragment
|
||||
AlertDialog loadingDialog = SimpleProgressDialog.show(requireContext());
|
||||
|
||||
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
|
||||
return UsernameUtil.fetchUuidForUsername(requireContext(), contact.getNumber());
|
||||
return UsernameUtil.fetchAciForUsername(requireContext(), contact.getNumber());
|
||||
}, uuid -> {
|
||||
loadingDialog.dismiss();
|
||||
if (uuid.isPresent()) {
|
||||
|
||||
@@ -75,7 +75,7 @@ public class NewConversationActivity extends ContactSelectionActivity
|
||||
SimpleTask.run(getLifecycle(), () -> {
|
||||
Recipient resolved = Recipient.external(this, number);
|
||||
|
||||
if (!resolved.isRegistered() || !resolved.hasUuid()) {
|
||||
if (!resolved.isRegistered() || !resolved.hasAci()) {
|
||||
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.");
|
||||
try {
|
||||
DirectoryHelper.refreshDirectoryFor(this, resolved, false);
|
||||
|
||||
@@ -56,7 +56,6 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.view.OneShotPreDrawListener;
|
||||
@@ -64,6 +63,8 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
@@ -322,23 +323,26 @@ public class VerifyIdentityActivity extends PassphraseRequiredActivity implement
|
||||
//noinspection WrongThread
|
||||
Recipient resolved = recipient.resolve();
|
||||
|
||||
if (FeatureFlags.verifyV2() && resolved.getUuid().isPresent()) {
|
||||
if (FeatureFlags.verifyV2() && resolved.getAci().isPresent()) {
|
||||
Log.i(TAG, "Using UUID (version 2).");
|
||||
version = 2;
|
||||
localId = UuidUtil.toByteArray(TextSecurePreferences.getLocalUuid(requireContext()));
|
||||
remoteId = UuidUtil.toByteArray(resolved.getUuid().get());
|
||||
localId = TextSecurePreferences.getLocalAci(requireContext()).toByteArray();
|
||||
remoteId = resolved.requireAci().toByteArray();
|
||||
} else if (!FeatureFlags.verifyV2() && resolved.getE164().isPresent()) {
|
||||
Log.i(TAG, "Using E164 (version 1).");
|
||||
version = 1;
|
||||
localId = TextSecurePreferences.getLocalNumber(requireContext()).getBytes();
|
||||
remoteId = resolved.requireE164().getBytes();
|
||||
} else {
|
||||
Log.w(TAG, String.format(Locale.ENGLISH, "Could not show proper verification! verifyV2: %s, hasUuid: %s, hasE164: %s", FeatureFlags.verifyV2(), resolved.getUuid().isPresent(), resolved.getE164().isPresent()));
|
||||
new AlertDialog.Builder(requireContext())
|
||||
.setMessage(getString(R.string.VerifyIdentityActivity_you_must_first_exchange_messages_in_order_to_view, resolved.getDisplayName(requireContext())))
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> requireActivity().finish())
|
||||
.setOnDismissListener(dialog -> requireActivity().finish())
|
||||
.show();
|
||||
Log.w(TAG, String.format(Locale.ENGLISH, "Could not show proper verification! verifyV2: %s, hasUuid: %s, hasE164: %s", FeatureFlags.verifyV2(), resolved.getAci().isPresent(), resolved.getE164().isPresent()));
|
||||
new MaterialAlertDialogBuilder(requireContext())
|
||||
.setMessage(getString(R.string.VerifyIdentityActivity_you_must_first_exchange_messages_in_order_to_view, resolved.getDisplayName(requireContext())))
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> requireActivity().finish())
|
||||
.setOnDismissListener(dialog -> {
|
||||
requireActivity().finish();
|
||||
dialog.dismiss();
|
||||
})
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -26,8 +26,8 @@ import org.thoughtcrime.securesms.util.Hex
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.Util
|
||||
import org.thoughtcrime.securesms.util.livedata.Store
|
||||
import org.whispersystems.signalservice.api.push.ACI
|
||||
import java.util.Objects
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Shows internal details about a recipient that you can view from the conversation settings.
|
||||
@@ -60,7 +60,7 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
|
||||
)
|
||||
|
||||
if (!recipient.isGroup) {
|
||||
val uuid = recipient.uuid.transform(UUID::toString).or("null")
|
||||
val uuid = recipient.aci.transform(ACI::toString).or("null")
|
||||
longClickPref(
|
||||
title = DSLSettingsText.from("UUID"),
|
||||
summary = DSLSettingsText.from(uuid),
|
||||
@@ -145,8 +145,8 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
|
||||
.setTitle("Are you sure?")
|
||||
.setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() }
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
if (recipient.hasUuid()) {
|
||||
DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireUuid().toString())
|
||||
if (recipient.hasAci()) {
|
||||
DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireAci().toString())
|
||||
}
|
||||
if (recipient.hasE164()) {
|
||||
DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireE164())
|
||||
|
||||
+2
-2
@@ -127,10 +127,10 @@ data class CallParticipantsState(
|
||||
fun getIncomingRingingGroupDescription(context: Context): String? {
|
||||
if (callState == WebRtcViewModel.State.CALL_INCOMING &&
|
||||
groupCallState == WebRtcViewModel.GroupCallState.RINGING &&
|
||||
ringerRecipient.hasUuid()
|
||||
ringerRecipient.hasAci()
|
||||
) {
|
||||
val ringerName = ringerRecipient.getShortDisplayName(context)
|
||||
val membersWithoutYouOrRinger: List<GroupMemberEntry.FullMember> = groupMembers.filterNot { it.member.isSelf || ringerRecipient.requireUuid() == it.member.uuid.orNull() }
|
||||
val membersWithoutYouOrRinger: List<GroupMemberEntry.FullMember> = groupMembers.filterNot { it.member.isSelf || ringerRecipient.requireAci() == it.member.aci.orNull() }
|
||||
|
||||
return when (membersWithoutYouOrRinger.size) {
|
||||
0 -> context.getString(R.string.WebRtcCallView__s_is_calling_you, ringerName)
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.push.IasTrustStore;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.TrustStore;
|
||||
import org.whispersystems.signalservice.internal.contacts.crypto.Quote;
|
||||
import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedQuoteException;
|
||||
@@ -66,7 +67,7 @@ class ContactDiscoveryV2 {
|
||||
KeyStore iasKeyStore = getIasKeyStore(context);
|
||||
|
||||
try {
|
||||
Map<String, UUID> results = accountManager.getRegisteredUsers(iasKeyStore, sanitizedNumbers, BuildConfig.CDS_MRENCLAVE);
|
||||
Map<String, ACI> results = accountManager.getRegisteredUsers(iasKeyStore, sanitizedNumbers, BuildConfig.CDS_MRENCLAVE);
|
||||
FuzzyPhoneNumberHelper.OutputResult outputResult = FuzzyPhoneNumberHelper.generateOutput(results, inputResult);
|
||||
|
||||
return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites(), ignoredNumbers);
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper.DirectoryResult;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -46,7 +47,7 @@ class ContactDiscoveryV3 {
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
|
||||
try {
|
||||
Map<String, UUID> results = accountManager.getRegisteredUsersWithCdsh(sanitizedNumbers, BuildConfig.CDSH_PUBLIC_KEY, BuildConfig.CDSH_CODE_HASH);
|
||||
Map<String, ACI> results = accountManager.getRegisteredUsersWithCdsh(sanitizedNumbers, BuildConfig.CDSH_PUBLIC_KEY, BuildConfig.CDSH_CODE_HASH);
|
||||
FuzzyPhoneNumberHelper.OutputResult outputResult = FuzzyPhoneNumberHelper.generateOutput(results, inputResult);
|
||||
|
||||
return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites(), ignoredNumbers);
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.database.MessageDatabase.InsertResult;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.BulkOperationsHandle;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
|
||||
@@ -67,7 +68,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
@@ -112,9 +112,9 @@ public class DirectoryHelper {
|
||||
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
|
||||
|
||||
for (Recipient recipient : recipients) {
|
||||
if (recipient.hasUuid() && !recipient.hasE164()) {
|
||||
if (isUuidRegistered(context, recipient)) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireUuid());
|
||||
if (recipient.hasAci() && !recipient.hasE164()) {
|
||||
if (isAciRegistered(context, recipient)) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci());
|
||||
} else {
|
||||
recipientDatabase.markUnregistered(recipient.getId());
|
||||
}
|
||||
@@ -136,11 +136,11 @@ public class DirectoryHelper {
|
||||
RegisteredState originalRegisteredState = recipient.resolve().getRegistered();
|
||||
RegisteredState newRegisteredState;
|
||||
|
||||
if (recipient.hasUuid() && !recipient.hasE164()) {
|
||||
boolean isRegistered = isUuidRegistered(context, recipient);
|
||||
if (recipient.hasAci() && !recipient.hasE164()) {
|
||||
boolean isRegistered = isAciRegistered(context, recipient);
|
||||
stopwatch.split("uuid-network");
|
||||
if (isRegistered) {
|
||||
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.getUuid().get());
|
||||
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci());
|
||||
if (idChanged) {
|
||||
Log.w(TAG, "ID changed during refresh by UUID.");
|
||||
}
|
||||
@@ -169,18 +169,18 @@ public class DirectoryHelper {
|
||||
}
|
||||
|
||||
if (result.getRegisteredNumbers().size() > 0) {
|
||||
UUID uuid = result.getRegisteredNumbers().values().iterator().next();
|
||||
if (uuid != null) {
|
||||
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), uuid);
|
||||
ACI aci = result.getRegisteredNumbers().values().iterator().next();
|
||||
if (aci != null) {
|
||||
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), aci);
|
||||
if (idChanged) {
|
||||
recipient = Recipient.resolved(recipientDatabase.getByUuid(uuid).get());
|
||||
recipient = Recipient.resolved(recipientDatabase.getByAci(aci).get());
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "Registered number set had a null UUID!");
|
||||
}
|
||||
} else if (recipient.hasUuid() && recipient.isRegistered() && hasCommunicatedWith(context, recipient)) {
|
||||
if (isUuidRegistered(context, recipient)) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireUuid());
|
||||
} else if (recipient.hasAci() && recipient.isRegistered() && hasCommunicatedWith(context, recipient)) {
|
||||
if (isAciRegistered(context, recipient)) {
|
||||
recipientDatabase.markRegistered(recipient.getId(), recipient.requireAci());
|
||||
} else {
|
||||
recipientDatabase.markUnregistered(recipient.getId());
|
||||
}
|
||||
@@ -245,10 +245,10 @@ public class DirectoryHelper {
|
||||
recipientDatabase.updatePhoneNumbers(result.getNumberRewrites());
|
||||
}
|
||||
|
||||
Map<RecipientId, String> uuidMap = recipientDatabase.bulkProcessCdsResult(result.getRegisteredNumbers());
|
||||
Set<String> activeNumbers = result.getRegisteredNumbers().keySet();
|
||||
Set<RecipientId> activeIds = uuidMap.keySet();
|
||||
Set<RecipientId> inactiveIds = Stream.of(allNumbers)
|
||||
Map<RecipientId, ACI> aciMap = recipientDatabase.bulkProcessCdsResult(result.getRegisteredNumbers());
|
||||
Set<String> activeNumbers = result.getRegisteredNumbers().keySet();
|
||||
Set<RecipientId> activeIds = aciMap.keySet();
|
||||
Set<RecipientId> inactiveIds = Stream.of(allNumbers)
|
||||
.filterNot(activeNumbers::contains)
|
||||
.filterNot(n -> result.getNumberRewrites().containsKey(n))
|
||||
.filterNot(n -> result.getIgnoredNumbers().contains(n))
|
||||
@@ -270,7 +270,7 @@ public class DirectoryHelper {
|
||||
|
||||
Set<RecipientId> preExistingRegisteredUsers = new HashSet<>(recipientDatabase.getRegistered());
|
||||
|
||||
recipientDatabase.bulkUpdatedRegisteredStatus(uuidMap, inactiveIds);
|
||||
recipientDatabase.bulkUpdatedRegisteredStatus(aciMap, inactiveIds);
|
||||
|
||||
stopwatch.split("update-registered");
|
||||
|
||||
@@ -298,7 +298,7 @@ public class DirectoryHelper {
|
||||
}
|
||||
|
||||
|
||||
private static boolean isUuidRegistered(@NonNull Context context, @NonNull Recipient recipient) throws IOException {
|
||||
private static boolean isAciRegistered(@NonNull Context context, @NonNull Recipient recipient) throws IOException {
|
||||
try {
|
||||
ProfileUtil.retrieveProfileSync(context, recipient, SignalServiceProfile.RequestType.PROFILE);
|
||||
return true;
|
||||
@@ -514,7 +514,7 @@ public class DirectoryHelper {
|
||||
List<Recipient> possiblyUnlisted = Stream.of(inactiveIds)
|
||||
.map(Recipient::resolved)
|
||||
.filter(Recipient::isRegistered)
|
||||
.filter(Recipient::hasUuid)
|
||||
.filter(Recipient::hasAci)
|
||||
.filter(r -> hasCommunicatedWith(context, r))
|
||||
.toList();
|
||||
|
||||
@@ -549,17 +549,17 @@ public class DirectoryHelper {
|
||||
}
|
||||
|
||||
private static boolean hasCommunicatedWith(@NonNull Context context, @NonNull Recipient recipient) {
|
||||
return DatabaseFactory.getThreadDatabase(context).hasThread(recipient.getId()) ||
|
||||
(recipient.hasUuid() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireUuid().toString())) ||
|
||||
return DatabaseFactory.getThreadDatabase(context).hasThread(recipient.getId()) ||
|
||||
(recipient.hasAci() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireAci().toString())) ||
|
||||
(recipient.hasE164() && DatabaseFactory.getSessionDatabase(context).hasSessionFor(recipient.requireE164()));
|
||||
}
|
||||
|
||||
static class DirectoryResult {
|
||||
private final Map<String, UUID> registeredNumbers;
|
||||
private final Map<String, ACI> registeredNumbers;
|
||||
private final Map<String, String> numberRewrites;
|
||||
private final Set<String> ignoredNumbers;
|
||||
|
||||
DirectoryResult(@NonNull Map<String, UUID> registeredNumbers,
|
||||
DirectoryResult(@NonNull Map<String, ACI> registeredNumbers,
|
||||
@NonNull Map<String, String> numberRewrites,
|
||||
@NonNull Set<String> ignoredNumbers)
|
||||
{
|
||||
@@ -569,7 +569,7 @@ public class DirectoryHelper {
|
||||
}
|
||||
|
||||
|
||||
@NonNull Map<String, UUID> getRegisteredNumbers() {
|
||||
@NonNull Map<String, ACI> getRegisteredNumbers() {
|
||||
return registeredNumbers;
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -4,6 +4,8 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -50,8 +52,8 @@ class FuzzyPhoneNumberHelper {
|
||||
* these results and our initial input set, we can decide if we need to rewrite which number we
|
||||
* have stored locally.
|
||||
*/
|
||||
static @NonNull OutputResult generateOutput(@NonNull Map<String, UUID> registeredNumbers, @NonNull InputResult inputResult) {
|
||||
Map<String, UUID> allNumbers = new HashMap<>(registeredNumbers);
|
||||
static @NonNull OutputResult generateOutput(@NonNull Map<String, ACI> registeredNumbers, @NonNull InputResult inputResult) {
|
||||
Map<String, ACI> allNumbers = new HashMap<>(registeredNumbers);
|
||||
Map<String, String> rewrites = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, String> entry : inputResult.getMapOfOriginalToVariant().entrySet()) {
|
||||
@@ -170,15 +172,15 @@ class FuzzyPhoneNumberHelper {
|
||||
}
|
||||
|
||||
public static class OutputResult {
|
||||
private final Map<String, UUID> numbers;
|
||||
private final Map<String, ACI> numbers;
|
||||
private final Map<String, String> rewrites;
|
||||
|
||||
private OutputResult(@NonNull Map<String, UUID> numbers, @NonNull Map<String, String> rewrites) {
|
||||
private OutputResult(@NonNull Map<String, ACI> numbers, @NonNull Map<String, String> rewrites) {
|
||||
this.numbers = numbers;
|
||||
this.rewrites = rewrites;
|
||||
}
|
||||
|
||||
public @NonNull Map<String, UUID> getNumbers() {
|
||||
public @NonNull Map<String, ACI> getNumbers() {
|
||||
return numbers;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,6 @@ import org.thoughtcrime.securesms.search.MessageResult;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.stickers.StickerEventListener;
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
@@ -1521,7 +1520,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
|
||||
sendButton.resetAvailableTransports(isMediaMessage);
|
||||
|
||||
if (!isSecureText && !isPushGroupConversation() && !recipient.get().isUuidOnly()) {
|
||||
if (!isSecureText && !isPushGroupConversation() && !recipient.get().isAciOnly()) {
|
||||
sendButton.disableTransport(Type.TEXTSECURE);
|
||||
}
|
||||
|
||||
@@ -1532,7 +1531,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
if (!recipient.get().isPushGroup() && recipient.get().isForceSmsSelection()) {
|
||||
sendButton.setDefaultTransport(Type.SMS);
|
||||
} else {
|
||||
if (isSecureText || isPushGroupConversation() || recipient.get().isUuidOnly()) {
|
||||
if (isSecureText || isPushGroupConversation() || recipient.get().isAciOnly()) {
|
||||
sendButton.setDefaultTransport(Type.TEXTSECURE);
|
||||
} else {
|
||||
sendButton.setDefaultTransport(Type.SMS);
|
||||
@@ -2942,7 +2941,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
return new SettableFuture<>(null);
|
||||
}
|
||||
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isUuidOnly();
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isAciOnly();
|
||||
final long thread = this.threadId;
|
||||
|
||||
if (sendPush) {
|
||||
@@ -3005,7 +3004,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
|
||||
final long thread = this.threadId;
|
||||
final Context context = getApplicationContext();
|
||||
final String messageBody = getMessage();
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isUuidOnly();
|
||||
final boolean sendPush = (isSecureText && !forceSms) || recipient.get().isAciOnly();
|
||||
|
||||
OutgoingTextMessage message;
|
||||
|
||||
|
||||
+4
-5
@@ -47,10 +47,9 @@ import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -343,11 +342,11 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||
});
|
||||
} else if (conversationMessage.getMessageRecord().isGroupCall()) {
|
||||
UpdateDescription updateDescription = MessageRecord.getGroupCallUpdateDescription(getContext(), conversationMessage.getMessageRecord().getBody(), true);
|
||||
Collection<UUID> uuids = updateDescription.getMentioned();
|
||||
Collection<ACI> acis = updateDescription.getMentioned();
|
||||
|
||||
int text = 0;
|
||||
if (Util.hasItems(uuids)) {
|
||||
if (uuids.contains(TextSecurePreferences.getLocalUuid(getContext()))) {
|
||||
if (Util.hasItems(acis)) {
|
||||
if (acis.contains(TextSecurePreferences.getLocalAci(getContext()))) {
|
||||
text = R.string.ConversationUpdateItem_return_to_call;
|
||||
} else if (GroupCallUpdateDetailsUtil.parse(conversationMessage.getMessageRecord().getBody()).getIsCallFull()) {
|
||||
text = R.string.ConversationUpdateItem_call_is_full;
|
||||
|
||||
+1
-3
@@ -5,8 +5,6 @@ import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.SessionUtil;
|
||||
@@ -124,7 +122,7 @@ public class TextSecureIdentityKeyStore implements IdentityKeyStore {
|
||||
|
||||
@Override
|
||||
public boolean isTrustedIdentity(SignalProtocolAddress address, IdentityKey identityKey, Direction direction) {
|
||||
boolean isSelf = address.getName().equals(TextSecurePreferences.getLocalUuid(context).toString()) ||
|
||||
boolean isSelf = address.getName().equals(TextSecurePreferences.getLocalAci(context).toString()) ||
|
||||
address.getName().equals(TextSecurePreferences.getLocalNumber(context));
|
||||
|
||||
if (isSelf) {
|
||||
|
||||
+2
-2
@@ -134,8 +134,8 @@ public class TextSecureSessionStore implements SignalServiceSessionStore {
|
||||
synchronized (LOCK) {
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
if (recipient.hasUuid()) {
|
||||
archiveSession(new SignalProtocolAddress(recipient.requireUuid().toString(), deviceId));
|
||||
if (recipient.hasAci()) {
|
||||
archiveSession(new SignalProtocolAddress(recipient.requireAci().toString(), deviceId));
|
||||
}
|
||||
|
||||
if (recipient.hasE164()) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor;
|
||||
import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
import org.thoughtcrime.securesms.groups.GroupAccessControl;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
@@ -804,10 +805,10 @@ private static final String[] GROUP_PROJECTION = {
|
||||
}
|
||||
|
||||
private static boolean gv2GroupActive(@NonNull DecryptedGroup decryptedGroup) {
|
||||
UUID uuid = Recipient.self().getUuid().get();
|
||||
ACI aci = Recipient.self().requireAci();
|
||||
|
||||
return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), uuid).isPresent() ||
|
||||
DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), uuid).isPresent();
|
||||
return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), aci.uuid()).isPresent() ||
|
||||
DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), aci.uuid()).isPresent();
|
||||
}
|
||||
|
||||
private List<RecipientId> getCurrentMembers(@NonNull GroupId groupId) {
|
||||
@@ -868,7 +869,7 @@ private static final String[] GROUP_PROJECTION = {
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||
Log.w(TAG, "Seen unknown UUID in members list");
|
||||
} else {
|
||||
groupMembers.add(RecipientId.from(uuid, null));
|
||||
groupMembers.add(RecipientId.from(ACI.from(uuid), null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1186,9 +1187,9 @@ private static final String[] GROUP_PROJECTION = {
|
||||
*/
|
||||
public boolean isPendingMember(@NonNull Recipient recipient) {
|
||||
if (isV2Group()) {
|
||||
Optional<UUID> uuid = recipient.getUuid();
|
||||
if (uuid.isPresent()) {
|
||||
return DecryptedGroupUtil.findPendingByUuid(requireV2GroupProperties().getDecryptedGroup().getPendingMembersList(), uuid.get())
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
if (aci.isPresent()) {
|
||||
return DecryptedGroupUtil.findPendingByUuid(requireV2GroupProperties().getDecryptedGroup().getPendingMembersList(), aci.get().uuid())
|
||||
.isPresent();
|
||||
}
|
||||
}
|
||||
@@ -1229,13 +1230,13 @@ private static final String[] GROUP_PROJECTION = {
|
||||
}
|
||||
|
||||
public boolean isAdmin(@NonNull Recipient recipient) {
|
||||
Optional<UUID> uuid = recipient.getUuid();
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
|
||||
if (!uuid.isPresent()) {
|
||||
if (!aci.isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return DecryptedGroupUtil.findMemberByUuid(getDecryptedGroup().getMembersList(), uuid.get())
|
||||
return DecryptedGroupUtil.findMemberByUuid(getDecryptedGroup().getMembersList(), aci.get().uuid())
|
||||
.transform(t -> t.getRole() == Member.Role.ADMINISTRATOR)
|
||||
.or(false);
|
||||
}
|
||||
@@ -1245,21 +1246,21 @@ private static final String[] GROUP_PROJECTION = {
|
||||
}
|
||||
|
||||
public MemberLevel memberLevel(@NonNull Recipient recipient) {
|
||||
Optional<UUID> uuid = recipient.getUuid();
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
|
||||
if (!uuid.isPresent()) {
|
||||
if (!aci.isPresent()) {
|
||||
return MemberLevel.NOT_A_MEMBER;
|
||||
}
|
||||
|
||||
DecryptedGroup decryptedGroup = getDecryptedGroup();
|
||||
|
||||
return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), uuid.get())
|
||||
return DecryptedGroupUtil.findMemberByUuid(decryptedGroup.getMembersList(), aci.get().uuid())
|
||||
.transform(member -> member.getRole() == Member.Role.ADMINISTRATOR
|
||||
? MemberLevel.ADMINISTRATOR
|
||||
: MemberLevel.FULL_MEMBER)
|
||||
.or(() -> DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), uuid.get())
|
||||
.or(() -> DecryptedGroupUtil.findPendingByUuid(decryptedGroup.getPendingMembersList(), aci.get().uuid())
|
||||
.transform(m -> MemberLevel.PENDING_MEMBER)
|
||||
.or(() -> DecryptedGroupUtil.findRequestingByUuid(decryptedGroup.getRequestingMembersList(), uuid.get())
|
||||
.or(() -> DecryptedGroupUtil.findRequestingByUuid(decryptedGroup.getRequestingMembersList(), aci.get().uuid())
|
||||
.transform(m -> MemberLevel.REQUESTING_MEMBER)
|
||||
.or(MemberLevel.NOT_A_MEMBER)));
|
||||
}
|
||||
@@ -1271,7 +1272,7 @@ private static final String[] GROUP_PROJECTION = {
|
||||
public List<RecipientId> getMemberRecipientIds(@NonNull MemberSet memberSet) {
|
||||
boolean includeSelf = memberSet.includeSelf;
|
||||
DecryptedGroup groupV2 = getDecryptedGroup();
|
||||
UUID selfUuid = Recipient.self().getUuid().get();
|
||||
UUID selfUuid = Recipient.self().requireAci().uuid();
|
||||
List<RecipientId> recipients = new ArrayList<>(groupV2.getMembersCount() + groupV2.getPendingMembersCount());
|
||||
int unknownMembers = 0;
|
||||
int unknownPending = 0;
|
||||
@@ -1280,7 +1281,7 @@ private static final String[] GROUP_PROJECTION = {
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||
unknownMembers++;
|
||||
} else if (includeSelf || !selfUuid.equals(uuid)) {
|
||||
recipients.add(RecipientId.from(uuid, null));
|
||||
recipients.add(RecipientId.from(ACI.from(uuid), null));
|
||||
}
|
||||
}
|
||||
if (memberSet.includePending) {
|
||||
@@ -1288,7 +1289,7 @@ private static final String[] GROUP_PROJECTION = {
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||
unknownPending++;
|
||||
} else if (includeSelf || !selfUuid.equals(uuid)) {
|
||||
recipients.add(RecipientId.from(uuid, null));
|
||||
recipients.add(RecipientId.from(ACI.from(uuid), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -105,7 +106,7 @@ public final class MentionUtil {
|
||||
BodyRangeList.Builder builder = BodyRangeList.newBuilder();
|
||||
|
||||
for (Mention mention : mentions) {
|
||||
String uuid = Recipient.resolved(mention.getRecipientId()).requireUuid().toString();
|
||||
String uuid = Recipient.resolved(mention.getRecipientId()).requireAci().toString();
|
||||
builder.addRanges(BodyRangeList.BodyRange.newBuilder()
|
||||
.setMentionUuid(uuid)
|
||||
.setStart(mention.getStart())
|
||||
@@ -121,7 +122,7 @@ public final class MentionUtil {
|
||||
return Stream.of(BodyRangeList.parseFrom(data).getRangesList())
|
||||
.filter(bodyRange -> bodyRange.getAssociatedValueCase() == BodyRangeList.BodyRange.AssociatedValueCase.MENTIONUUID)
|
||||
.map(mention -> {
|
||||
RecipientId id = Recipient.externalPush(context, UuidUtil.parseOrThrow(mention.getMentionUuid()), null, false).getId();
|
||||
RecipientId id = Recipient.externalPush(context, ACI.parseOrThrow(mention.getMentionUuid()), null, false).getId();
|
||||
return new Mention(id, mention.getStart(), mention.getLength());
|
||||
})
|
||||
.toList();
|
||||
|
||||
@@ -81,6 +81,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
@@ -1559,7 +1560,7 @@ public class MmsDatabase extends MessageDatabase {
|
||||
MessageGroupContext.GroupV2Properties groupV2Properties = outgoingGroupUpdateMessage.requireGroupV2Properties();
|
||||
members.addAll(Stream.of(groupV2Properties.getAllActivePendingAndRemovedMembers())
|
||||
.distinct()
|
||||
.map(uuid -> RecipientId.from(uuid, null))
|
||||
.map(uuid -> RecipientId.from(ACI.from(uuid), null))
|
||||
.toList());
|
||||
members.remove(Recipient.self().getId());
|
||||
} else {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BadgeList;
|
||||
@@ -80,7 +81,6 @@ import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV2Record;
|
||||
import org.whispersystems.signalservice.api.storage.StorageId;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@@ -107,7 +107,7 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
static final String TABLE_NAME = "recipient";
|
||||
public static final String ID = "_id";
|
||||
private static final String UUID = "uuid";
|
||||
private static final String ACI_COLUMN = "uuid";
|
||||
private static final String USERNAME = "username";
|
||||
public static final String PHONE = "phone";
|
||||
public static final String EMAIL = "email";
|
||||
@@ -178,7 +178,7 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
|
||||
private static final String[] RECIPIENT_PROJECTION = new String[] {
|
||||
ID, UUID, USERNAME, PHONE, EMAIL, GROUP_ID, GROUP_TYPE,
|
||||
ID, ACI_COLUMN, USERNAME, PHONE, EMAIL, GROUP_ID, GROUP_TYPE,
|
||||
BLOCKED, MESSAGE_RINGTONE, CALL_RINGTONE, MESSAGE_VIBRATE, CALL_VIBRATE, MUTE_UNTIL, AVATAR_COLOR, SEEN_INVITE_REMINDER, DEFAULT_SUBSCRIPTION_ID, MESSAGE_EXPIRATION_TIME, REGISTERED,
|
||||
PROFILE_KEY, PROFILE_KEY_CREDENTIAL,
|
||||
SYSTEM_JOINED_NAME, SYSTEM_GIVEN_NAME, SYSTEM_FAMILY_NAME, SYSTEM_PHOTO_URI, SYSTEM_PHONE_LABEL, SYSTEM_PHONE_TYPE, SYSTEM_CONTACT_URI,
|
||||
@@ -329,7 +329,7 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
public static final String CREATE_TABLE =
|
||||
"CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
UUID + " TEXT UNIQUE DEFAULT NULL, " +
|
||||
ACI_COLUMN + " TEXT UNIQUE DEFAULT NULL, " +
|
||||
USERNAME + " TEXT UNIQUE DEFAULT NULL, " +
|
||||
PHONE + " TEXT UNIQUE DEFAULT NULL, " +
|
||||
EMAIL + " TEXT UNIQUE DEFAULT NULL, " +
|
||||
@@ -398,7 +398,7 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
public @NonNull boolean containsPhoneOrUuid(@NonNull String id) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String query = UUID + " = ? OR " + PHONE + " = ?";
|
||||
String query = ACI_COLUMN + " = ? OR " + PHONE + " = ?";
|
||||
String[] args = new String[]{id, id};
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, new String[] { ID }, query, args, null, null, null)) {
|
||||
@@ -421,8 +421,8 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
|
||||
public @NonNull
|
||||
Optional<RecipientId> getByUuid(@NonNull UUID uuid) {
|
||||
return getByColumn(UUID, uuid.toString());
|
||||
Optional<RecipientId> getByAci(@NonNull ACI uuid) {
|
||||
return getByColumn(ACI_COLUMN, uuid.toString());
|
||||
}
|
||||
|
||||
public @NonNull
|
||||
@@ -430,12 +430,12 @@ public class RecipientDatabase extends Database {
|
||||
return getByColumn(USERNAME, username);
|
||||
}
|
||||
|
||||
public @NonNull RecipientId getAndPossiblyMerge(@Nullable UUID uuid, @Nullable String e164, boolean highTrust) {
|
||||
return getAndPossiblyMerge(uuid, e164, highTrust, false);
|
||||
public @NonNull RecipientId getAndPossiblyMerge(@Nullable ACI aci, @Nullable String e164, boolean highTrust) {
|
||||
return getAndPossiblyMerge(aci, e164, highTrust, false);
|
||||
}
|
||||
|
||||
public @NonNull RecipientId getAndPossiblyMerge(@Nullable UUID uuid, @Nullable String e164, boolean highTrust, boolean changeSelf) {
|
||||
if (uuid == null && e164 == null) {
|
||||
public @NonNull RecipientId getAndPossiblyMerge(@Nullable ACI aci, @Nullable String e164, boolean highTrust, boolean changeSelf) {
|
||||
if (aci == null && e164 == null) {
|
||||
throw new IllegalArgumentException("Must provide a UUID or E164!");
|
||||
}
|
||||
|
||||
@@ -449,115 +449,115 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
try {
|
||||
Optional<RecipientId> byE164 = e164 != null ? getByE164(e164) : Optional.absent();
|
||||
Optional<RecipientId> byUuid = uuid != null ? getByUuid(uuid) : Optional.absent();
|
||||
Optional<RecipientId> byAci = aci != null ? getByAci(aci) : Optional.absent();
|
||||
|
||||
RecipientId finalId;
|
||||
|
||||
if (!byE164.isPresent() && !byUuid.isPresent()) {
|
||||
if (!byE164.isPresent() && !byAci.isPresent()) {
|
||||
Log.i(TAG, "Discovered a completely new user. Inserting.", true);
|
||||
if (highTrust) {
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(e164, uuid));
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(e164, aci));
|
||||
finalId = RecipientId.from(id);
|
||||
} else {
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(uuid == null ? e164 : null, uuid));
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(aci == null ? e164 : null, aci));
|
||||
finalId = RecipientId.from(id);
|
||||
}
|
||||
} else if (byE164.isPresent() && !byUuid.isPresent()) {
|
||||
if (uuid != null) {
|
||||
} else if (byE164.isPresent() && !byAci.isPresent()) {
|
||||
if (aci != null) {
|
||||
RecipientSettings e164Settings = getRecipientSettings(byE164.get());
|
||||
if (e164Settings.uuid != null) {
|
||||
if (e164Settings.aci != null) {
|
||||
if (highTrust) {
|
||||
Log.w(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s), but that user already has a UUID (%s). Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to a new entry.", uuid, byE164.get(), e164Settings.uuid), true);
|
||||
Log.w(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s), but that user already has an ACI (%s). Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to a new entry.", aci, byE164.get(), e164Settings.aci), true);
|
||||
|
||||
removePhoneNumber(byE164.get(), db);
|
||||
recipientNeedingRefresh = byE164.get();
|
||||
|
||||
ContentValues insertValues = buildContentValuesForNewUser(e164, uuid);
|
||||
ContentValues insertValues = buildContentValuesForNewUser(e164, aci);
|
||||
insertValues.put(BLOCKED, e164Settings.blocked ? 1 : 0);
|
||||
|
||||
long id = db.insert(TABLE_NAME, null, insertValues);
|
||||
finalId = RecipientId.from(id);
|
||||
} else {
|
||||
Log.w(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s), but that user already has a UUID (%s). Likely a case of re-registration. Low-trust, so making a new user for the UUID.", uuid, byE164.get(), e164Settings.uuid), true);
|
||||
Log.w(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s), but that user already has an ACI (%s). Likely a case of re-registration. Low-trust, so making a new user for the UUID.", aci, byE164.get(), e164Settings.aci), true);
|
||||
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, uuid));
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, aci));
|
||||
finalId = RecipientId.from(id);
|
||||
}
|
||||
} else {
|
||||
if (highTrust) {
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s). High-trust, so updating.", uuid, byE164.get()), true);
|
||||
markRegisteredOrThrow(byE164.get(), uuid);
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s). High-trust, so updating.", aci, byE164.get()), true);
|
||||
markRegisteredOrThrow(byE164.get(), aci);
|
||||
finalId = byE164.get();
|
||||
} else {
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about a UUID (%s) for a known E164 user (%s). Low-trust, so making a new user for the UUID.", uuid, byE164.get()), true);
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, uuid));
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about an ACI (%s) for a known E164 user (%s). Low-trust, so making a new user for the ACI.", aci, byE164.get()), true);
|
||||
long id = db.insert(TABLE_NAME, null, buildContentValuesForNewUser(null, aci));
|
||||
finalId = RecipientId.from(id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
finalId = byE164.get();
|
||||
}
|
||||
} else if (!byE164.isPresent() && byUuid.isPresent()) {
|
||||
} else if (!byE164.isPresent() && byAci.isPresent()) {
|
||||
if (e164 != null) {
|
||||
if (highTrust) {
|
||||
if (Objects.equals(uuid, TextSecurePreferences.getLocalUuid(context)) && !changeSelf) {
|
||||
Log.w(TAG, String.format(Locale.US, "Found out about an E164 (%s) for our own UUID user (%s). High-trust but not change self, doing nothing.", e164, byUuid.get()), true);
|
||||
finalId = byUuid.get();
|
||||
if (Objects.equals(aci, TextSecurePreferences.getLocalAci(context)) && !changeSelf) {
|
||||
Log.w(TAG, String.format(Locale.US, "Found out about an E164 (%s) for our own ACI user (%s). High-trust but not change self, doing nothing.", e164, byAci.get()), true);
|
||||
finalId = byAci.get();
|
||||
} else {
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known UUID user (%s). High-trust, so updating.", e164, byUuid.get()), true);
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known ACI user (%s). High-trust, so updating.", e164, byAci.get()), true);
|
||||
|
||||
RecipientSettings byUuidSettings = getRecipientSettings(byUuid.get());
|
||||
RecipientSettings byUuidSettings = getRecipientSettings(byAci.get());
|
||||
|
||||
setPhoneNumberOrThrow(byUuid.get(), e164);
|
||||
finalId = byUuid.get();
|
||||
setPhoneNumberOrThrow(byAci.get(), e164);
|
||||
finalId = byAci.get();
|
||||
|
||||
if (!Util.isEmpty(byUuidSettings.e164) && !byUuidSettings.e164.equals(e164)) {
|
||||
recipientChangedNumber = finalId;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known UUID user (%s). Low-trust, so doing nothing.", e164, byUuid.get()), true);
|
||||
finalId = byUuid.get();
|
||||
Log.i(TAG, String.format(Locale.US, "Found out about an E164 (%s) for a known ACI user (%s). Low-trust, so doing nothing.", e164, byAci.get()), true);
|
||||
finalId = byAci.get();
|
||||
}
|
||||
} else {
|
||||
finalId = byUuid.get();
|
||||
finalId = byAci.get();
|
||||
}
|
||||
} else {
|
||||
if (byE164.equals(byUuid)) {
|
||||
finalId = byUuid.get();
|
||||
if (byE164.equals(byAci)) {
|
||||
finalId = byAci.get();
|
||||
} else {
|
||||
Log.w(TAG, String.format(Locale.US, "Hit a conflict between %s (E164 of %s) and %s (UUID %s). They map to different recipients.", byE164.get(), e164, byUuid.get(), uuid), new Throwable(), true);
|
||||
Log.w(TAG, String.format(Locale.US, "Hit a conflict between %s (E164 of %s) and %s (ACI %s). They map to different recipients.", byE164.get(), e164, byAci.get(), aci), new Throwable(), true);
|
||||
|
||||
RecipientSettings e164Settings = getRecipientSettings(byE164.get());
|
||||
|
||||
if (e164Settings.getUuid() != null) {
|
||||
if (e164Settings.getAci() != null) {
|
||||
if (highTrust) {
|
||||
Log.w(TAG, "The E164 contact has a different UUID. Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to the UUID entry.", true);
|
||||
Log.w(TAG, "The E164 contact has a different ACI. Likely a case of re-registration. High-trust, so stripping the E164 from the existing account and assigning it to the ACI entry.", true);
|
||||
|
||||
removePhoneNumber(byE164.get(), db);
|
||||
recipientNeedingRefresh = byE164.get();
|
||||
|
||||
RecipientSettings byUuidSettings = getRecipientSettings(byUuid.get());
|
||||
RecipientSettings byUuidSettings = getRecipientSettings(byAci.get());
|
||||
|
||||
setPhoneNumberOrThrow(byUuid.get(), Objects.requireNonNull(e164));
|
||||
finalId = byUuid.get();
|
||||
setPhoneNumberOrThrow(byAci.get(), Objects.requireNonNull(e164));
|
||||
finalId = byAci.get();
|
||||
|
||||
if (!Util.isEmpty(byUuidSettings.e164) && !byUuidSettings.e164.equals(e164)) {
|
||||
recipientChangedNumber = finalId;
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "The E164 contact has a different UUID. Likely a case of re-registration. Low-trust, so doing nothing.", true);
|
||||
finalId = byUuid.get();
|
||||
Log.w(TAG, "The E164 contact has a different ACI. Likely a case of re-registration. Low-trust, so doing nothing.", true);
|
||||
finalId = byAci.get();
|
||||
}
|
||||
} else {
|
||||
if (highTrust) {
|
||||
Log.w(TAG, "We have one contact with just an E164, and another with UUID. High-trust, so merging the two rows together.", true);
|
||||
finalId = merge(byUuid.get(), byE164.get());
|
||||
recipientNeedingRefresh = byUuid.get();
|
||||
remapped = new Pair<>(byE164.get(), byUuid.get());
|
||||
Log.w(TAG, "We have one contact with just an E164, and another with just an ACI. High-trust, so merging the two rows together.", true);
|
||||
finalId = merge(byAci.get(), byE164.get());
|
||||
recipientNeedingRefresh = byAci.get();
|
||||
remapped = new Pair<>(byE164.get(), byAci.get());
|
||||
} else {
|
||||
Log.w(TAG, "We have one contact with just an E164, and another with UUID. Low-trust, so doing nothing.", true);
|
||||
finalId = byUuid.get();
|
||||
Log.w(TAG, "We have one contact with just an E164, and another with just an ACI. Low-trust, so doing nothing.", true);
|
||||
finalId = byAci.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -592,13 +592,13 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
private static ContentValues buildContentValuesForNewUser(@Nullable String e164, @Nullable UUID uuid) {
|
||||
private static ContentValues buildContentValuesForNewUser(@Nullable String e164, @Nullable ACI aci) {
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(PHONE, e164);
|
||||
|
||||
if (uuid != null) {
|
||||
values.put(UUID, uuid.toString().toLowerCase());
|
||||
if (aci != null) {
|
||||
values.put(ACI_COLUMN, aci.toString().toLowerCase());
|
||||
values.put(REGISTERED, RegisteredState.REGISTERED.getId());
|
||||
values.put(STORAGE_SERVICE_ID, Base64.encodeBytes(StorageSyncHelper.generateKey()));
|
||||
values.put(AVATAR_COLOR, AvatarColor.random().serialize());
|
||||
@@ -608,8 +608,8 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
|
||||
|
||||
public @NonNull RecipientId getOrInsertFromUuid(@NonNull UUID uuid) {
|
||||
return getOrInsertByColumn(UUID, uuid.toString()).recipientId;
|
||||
public @NonNull RecipientId getOrInsertFromAci(@NonNull ACI aci) {
|
||||
return getOrInsertByColumn(ACI_COLUMN, aci.toString()).recipientId;
|
||||
}
|
||||
|
||||
public @NonNull RecipientId getOrInsertFromE164(@NonNull String e164) {
|
||||
@@ -829,13 +829,13 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
if (id < 0) {
|
||||
Log.w(TAG, "[applyStorageSyncContactInsert] Failed to insert. Possibly merging.");
|
||||
recipientId = getAndPossiblyMerge(insert.getAddress().hasValidUuid() ? insert.getAddress().getUuid() : null, insert.getAddress().getNumber().get(), true);
|
||||
recipientId = getAndPossiblyMerge(insert.getAddress().hasValidAci() ? insert.getAddress().getAci() : null, insert.getAddress().getNumber().get(), true);
|
||||
db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId));
|
||||
} else {
|
||||
recipientId = RecipientId.from(id);
|
||||
}
|
||||
|
||||
if (insert.getIdentityKey().isPresent() && insert.getAddress().hasValidUuid()) {
|
||||
if (insert.getIdentityKey().isPresent() && insert.getAddress().hasValidAci()) {
|
||||
try {
|
||||
IdentityKey identityKey = new IdentityKey(insert.getIdentityKey().get(), 0);
|
||||
|
||||
@@ -864,7 +864,7 @@ public class RecipientDatabase extends Database {
|
||||
RecipientId recipientId = getByColumn(STORAGE_SERVICE_ID, Base64.encodeBytes(update.getOld().getId().getRaw())).get();
|
||||
Log.w(TAG, "[applyStorageSyncContactUpdate] Found user " + recipientId + ". Possibly merging.");
|
||||
|
||||
recipientId = getAndPossiblyMerge(update.getNew().getAddress().hasValidUuid() ? update.getNew().getAddress().getUuid() : null, update.getNew().getAddress().getNumber().orNull(), true);
|
||||
recipientId = getAndPossiblyMerge(update.getNew().getAddress().hasValidAci() ? update.getNew().getAddress().getAci() : null, update.getNew().getAddress().getNumber().orNull(), true);
|
||||
Log.w(TAG, "[applyStorageSyncContactUpdate] Merged into " + recipientId);
|
||||
|
||||
db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId));
|
||||
@@ -881,7 +881,7 @@ public class RecipientDatabase extends Database {
|
||||
try {
|
||||
Optional<IdentityRecord> oldIdentityRecord = identityStore.getIdentityRecord(recipientId);
|
||||
|
||||
if (update.getNew().getIdentityKey().isPresent() && update.getNew().getAddress().hasValidUuid()) {
|
||||
if (update.getNew().getIdentityKey().isPresent() && update.getNew().getAddress().hasValidAci()) {
|
||||
IdentityKey identityKey = new IdentityKey(update.getNew().getIdentityKey().get(), 0);
|
||||
DatabaseFactory.getIdentityDatabase(context).updateIdentityAfterSync(update.getNew().getAddress().getIdentifier(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(update.getNew().getIdentityState()));
|
||||
}
|
||||
@@ -1059,8 +1059,8 @@ public class RecipientDatabase extends Database {
|
||||
ProfileName profileName = ProfileName.fromParts(contact.getGivenName().orNull(), contact.getFamilyName().orNull());
|
||||
String username = contact.getUsername().orNull();
|
||||
|
||||
if (contact.getAddress().hasValidUuid()) {
|
||||
values.put(UUID, contact.getAddress().getUuid().toString());
|
||||
if (contact.getAddress().hasValidAci()) {
|
||||
values.put(ACI_COLUMN, contact.getAddress().getAci().toString());
|
||||
}
|
||||
|
||||
values.put(PHONE, contact.getAddress().getNumber().orNull());
|
||||
@@ -1133,9 +1133,9 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
private List<RecipientSettings> getRecipientSettingsForSync(@Nullable String query, @Nullable String[] args) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String table = TABLE_NAME + " LEFT OUTER JOIN " + IdentityDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + UUID + " = " + IdentityDatabase.TABLE_NAME + "." + IdentityDatabase.ADDRESS
|
||||
+ " LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + GROUP_ID + " = " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID
|
||||
+ " LEFT OUTER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID;
|
||||
String table = TABLE_NAME + " LEFT OUTER JOIN " + IdentityDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + ACI_COLUMN + " = " + IdentityDatabase.TABLE_NAME + "." + IdentityDatabase.ADDRESS
|
||||
+ " LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + GROUP_ID + " = " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID
|
||||
+ " LEFT OUTER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + TABLE_NAME + "." + ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID;
|
||||
List<RecipientSettings> out = new ArrayList<>();
|
||||
|
||||
String[] columns = Stream.of(TYPED_RECIPIENT_PROJECTION,
|
||||
@@ -1169,7 +1169,7 @@ public class RecipientDatabase extends Database {
|
||||
*/
|
||||
public @NonNull Map<RecipientId, StorageId> getContactStorageSyncIdsMap() {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String query = STORAGE_SERVICE_ID + " NOT NULL AND " + UUID + " NOT NULL AND " + ID + " != ? AND " + GROUP_TYPE + " != ?";
|
||||
String query = STORAGE_SERVICE_ID + " NOT NULL AND " + ACI_COLUMN + " NOT NULL AND " + ID + " != ? AND " + GROUP_TYPE + " != ?";
|
||||
String[] args = SqlUtil.buildArgs(Recipient.self().getId(), String.valueOf(GroupType.SIGNAL_V2.getId()));
|
||||
Map<RecipientId, StorageId> out = new HashMap<>();
|
||||
|
||||
@@ -1215,7 +1215,7 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
static @NonNull RecipientSettings getRecipientSettings(@NonNull Context context, @NonNull Cursor cursor, @NonNull String idColumnName) {
|
||||
long id = CursorUtil.requireLong(cursor, idColumnName);
|
||||
UUID uuid = UuidUtil.parseOrNull(CursorUtil.requireString(cursor, UUID));
|
||||
ACI uuid = ACI.parseOrNull(CursorUtil.requireString(cursor, ACI_COLUMN));
|
||||
String username = CursorUtil.requireString(cursor, USERNAME);
|
||||
String e164 = CursorUtil.requireString(cursor, PHONE);
|
||||
String email = CursorUtil.requireString(cursor, EMAIL);
|
||||
@@ -1840,9 +1840,9 @@ public class RecipientDatabase extends Database {
|
||||
* database if missing.
|
||||
*/
|
||||
public Set<RecipientId> persistProfileKeySet(@NonNull ProfileKeySet profileKeySet) {
|
||||
Map<UUID, ProfileKey> profileKeys = profileKeySet.getProfileKeys();
|
||||
Map<UUID, ProfileKey> authoritativeProfileKeys = profileKeySet.getAuthoritativeProfileKeys();
|
||||
int totalKeys = profileKeys.size() + authoritativeProfileKeys.size();
|
||||
Map<ACI, ProfileKey> profileKeys = profileKeySet.getProfileKeys();
|
||||
Map<ACI, ProfileKey> authoritativeProfileKeys = profileKeySet.getAuthoritativeProfileKeys();
|
||||
int totalKeys = profileKeys.size() + authoritativeProfileKeys.size();
|
||||
|
||||
if (totalKeys == 0) {
|
||||
return Collections.emptySet();
|
||||
@@ -1853,8 +1853,8 @@ public class RecipientDatabase extends Database {
|
||||
HashSet<RecipientId> updated = new HashSet<>(totalKeys);
|
||||
RecipientId selfId = Recipient.self().getId();
|
||||
|
||||
for (Map.Entry<UUID, ProfileKey> entry : profileKeys.entrySet()) {
|
||||
RecipientId recipientId = getOrInsertFromUuid(entry.getKey());
|
||||
for (Map.Entry<ACI, ProfileKey> entry : profileKeys.entrySet()) {
|
||||
RecipientId recipientId = getOrInsertFromAci(entry.getKey());
|
||||
|
||||
if (setProfileKeyIfAbsent(recipientId, entry.getValue())) {
|
||||
Log.i(TAG, "Learned new profile key");
|
||||
@@ -1862,8 +1862,8 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<UUID, ProfileKey> entry : authoritativeProfileKeys.entrySet()) {
|
||||
RecipientId recipientId = getOrInsertFromUuid(entry.getKey());
|
||||
for (Map.Entry<ACI, ProfileKey> entry : authoritativeProfileKeys.entrySet()) {
|
||||
RecipientId recipientId = getOrInsertFromAci(entry.getKey());
|
||||
|
||||
if (selfId.equals(recipientId)) {
|
||||
Log.i(TAG, "Seen authoritative update for self");
|
||||
@@ -2111,7 +2111,7 @@ public class RecipientDatabase extends Database {
|
||||
Log.w(TAG, "[setPhoneNumber] Hit a conflict when trying to update " + id + ". Possibly merging.");
|
||||
|
||||
RecipientSettings existing = getRecipientSettings(id);
|
||||
RecipientId newId = getAndPossiblyMerge(existing.getUuid(), e164, true);
|
||||
RecipientId newId = getAndPossiblyMerge(existing.getAci(), e164, true);
|
||||
Log.w(TAG, "[setPhoneNumber] Resulting id: " + newId);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
@@ -2147,7 +2147,7 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
try {
|
||||
RecipientId id = Recipient.self().getId();
|
||||
RecipientId newId = getAndPossiblyMerge(Recipient.self().requireUuid(), e164, true, true);
|
||||
RecipientId newId = getAndPossiblyMerge(Recipient.self().requireAci(), e164, true, true);
|
||||
|
||||
if (id.equals(newId)) {
|
||||
Log.i(TAG, "[updateSelfPhone] Phone updated for self");
|
||||
@@ -2206,19 +2206,19 @@ public class RecipientDatabase extends Database {
|
||||
/**
|
||||
* @return True if setting the UUID resulted in changed recipientId, otherwise false.
|
||||
*/
|
||||
public boolean markRegistered(@NonNull RecipientId id, @NonNull UUID uuid) {
|
||||
public boolean markRegistered(@NonNull RecipientId id, @NonNull ACI aci) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
db.beginTransaction();
|
||||
|
||||
try {
|
||||
markRegisteredOrThrow(id, uuid);
|
||||
markRegisteredOrThrow(id, aci);
|
||||
db.setTransactionSuccessful();
|
||||
return false;
|
||||
} catch (SQLiteConstraintException e) {
|
||||
Log.w(TAG, "[markRegistered] Hit a conflict when trying to update " + id + ". Possibly merging.");
|
||||
|
||||
RecipientSettings existing = getRecipientSettings(id);
|
||||
RecipientId newId = getAndPossiblyMerge(uuid, existing.getE164(), true);
|
||||
RecipientId newId = getAndPossiblyMerge(aci, existing.getE164(), true);
|
||||
Log.w(TAG, "[markRegistered] Merged into " + newId);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
@@ -2231,10 +2231,10 @@ public class RecipientDatabase extends Database {
|
||||
/**
|
||||
* Should only use if you are confident that this shouldn't result in any contact merging.
|
||||
*/
|
||||
public void markRegisteredOrThrow(@NonNull RecipientId id, @NonNull UUID uuid) {
|
||||
public void markRegisteredOrThrow(@NonNull RecipientId id, @NonNull ACI aci) {
|
||||
ContentValues contentValues = new ContentValues(2);
|
||||
contentValues.put(REGISTERED, RegisteredState.REGISTERED.getId());
|
||||
contentValues.put(UUID, uuid.toString().toLowerCase());
|
||||
contentValues.put(ACI_COLUMN, aci.toString().toLowerCase());
|
||||
|
||||
if (update(id, contentValues)) {
|
||||
setStorageIdIfNotSet(id);
|
||||
@@ -2252,28 +2252,31 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public void bulkUpdatedRegisteredStatus(@NonNull Map<RecipientId, String> registered, Collection<RecipientId> unregistered) {
|
||||
public void bulkUpdatedRegisteredStatus(@NonNull Map<RecipientId, ACI> registered, Collection<RecipientId> unregistered) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
db.beginTransaction();
|
||||
|
||||
try {
|
||||
for (Map.Entry<RecipientId, String> entry : registered.entrySet()) {
|
||||
for (Map.Entry<RecipientId, ACI> entry : registered.entrySet()) {
|
||||
RecipientId recipientId = entry.getKey();
|
||||
ACI aci = entry.getValue();
|
||||
|
||||
ContentValues values = new ContentValues(2);
|
||||
values.put(REGISTERED, RegisteredState.REGISTERED.getId());
|
||||
|
||||
if (entry.getValue() != null) {
|
||||
values.put(UUID, entry.getValue().toLowerCase());
|
||||
if (aci != null) {
|
||||
values.put(ACI_COLUMN, aci.toString().toLowerCase());
|
||||
}
|
||||
|
||||
try {
|
||||
if (update(entry.getKey(), values)) {
|
||||
setStorageIdIfNotSet(entry.getKey());
|
||||
if (update(recipientId, values)) {
|
||||
setStorageIdIfNotSet(recipientId);
|
||||
}
|
||||
} catch (SQLiteConstraintException e) {
|
||||
Log.w(TAG, "[bulkUpdateRegisteredStatus] Hit a conflict when trying to update " + entry.getKey() + ". Possibly merging.");
|
||||
Log.w(TAG, "[bulkUpdateRegisteredStatus] Hit a conflict when trying to update " + recipientId + ". Possibly merging.");
|
||||
|
||||
RecipientSettings existing = getRecipientSettings(entry.getKey());
|
||||
RecipientId newId = getAndPossiblyMerge(UuidUtil.parseOrThrow(entry.getValue()), existing.getE164(), true);
|
||||
RecipientId newId = getAndPossiblyMerge(aci, existing.getE164(), true);
|
||||
Log.w(TAG, "[bulkUpdateRegisteredStatus] Merged into " + newId);
|
||||
}
|
||||
}
|
||||
@@ -2298,27 +2301,27 @@ public class RecipientDatabase extends Database {
|
||||
*
|
||||
* @return A mapping of (RecipientId, UUID)
|
||||
*/
|
||||
public @NonNull Map<RecipientId, String> bulkProcessCdsResult(@NonNull Map<String, UUID> mapping) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
HashMap<RecipientId, String> uuidMap = new HashMap<>();
|
||||
public @NonNull Map<RecipientId, ACI> bulkProcessCdsResult(@NonNull Map<String, ACI> mapping) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
HashMap<RecipientId, ACI> aciMap = new HashMap<>();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (Map.Entry<String, UUID> entry : mapping.entrySet()) {
|
||||
for (Map.Entry<String, ACI> entry : mapping.entrySet()) {
|
||||
String e164 = entry.getKey();
|
||||
UUID uuid = entry.getValue();
|
||||
Optional<RecipientId> uuidEntry = uuid != null ? getByUuid(uuid) : Optional.absent();
|
||||
ACI aci = entry.getValue();
|
||||
Optional<RecipientId> aciEntry = aci != null ? getByAci(aci) : Optional.absent();
|
||||
|
||||
if (uuidEntry.isPresent()) {
|
||||
boolean idChanged = setPhoneNumber(uuidEntry.get(), e164);
|
||||
if (aciEntry.isPresent()) {
|
||||
boolean idChanged = setPhoneNumber(aciEntry.get(), e164);
|
||||
if (idChanged) {
|
||||
uuidEntry = getByUuid(Objects.requireNonNull(uuid));
|
||||
aciEntry = getByAci(Objects.requireNonNull(aci));
|
||||
}
|
||||
}
|
||||
|
||||
RecipientId id = uuidEntry.isPresent() ? uuidEntry.get() : getOrInsertFromE164(e164);
|
||||
RecipientId id = aciEntry.isPresent() ? aciEntry.get() : getOrInsertFromE164(e164);
|
||||
|
||||
uuidMap.put(id, uuid != null ? uuid.toString() : null);
|
||||
aciMap.put(id, aci);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
@@ -2326,7 +2329,7 @@ public class RecipientDatabase extends Database {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
return uuidMap;
|
||||
return aciMap;
|
||||
}
|
||||
|
||||
public @NonNull List<RecipientId> getUninvitedRecipientsForInsights() {
|
||||
@@ -2730,7 +2733,7 @@ public class RecipientDatabase extends Database {
|
||||
.map(b -> b.getNumber().get())
|
||||
.toList();
|
||||
List<String> blockedUuid = Stream.of(blocked)
|
||||
.map(b -> b.getUuid().toString().toLowerCase())
|
||||
.map(b -> b.getAci().toString().toLowerCase())
|
||||
.toList();
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
@@ -2750,7 +2753,7 @@ public class RecipientDatabase extends Database {
|
||||
}
|
||||
|
||||
for (String uuid : blockedUuid) {
|
||||
db.update(TABLE_NAME, setBlocked, UUID + " = ?", new String[] { uuid });
|
||||
db.update(TABLE_NAME, setBlocked, ACI_COLUMN + " = ?", new String[] { uuid });
|
||||
}
|
||||
|
||||
List<GroupId.V1> groupIdStrings = new ArrayList<>(groupIds.size());
|
||||
@@ -3106,7 +3109,7 @@ public class RecipientDatabase extends Database {
|
||||
SessionDatabase sessionDatabase = DatabaseFactory.getSessionDatabase(context);
|
||||
|
||||
boolean hasE164Session = sessionDatabase.getAllFor(e164Settings.e164).size() > 0;
|
||||
boolean hasUuidSession = sessionDatabase.getAllFor(uuidSettings.uuid.toString()).size() > 0;
|
||||
boolean hasUuidSession = sessionDatabase.getAllFor(uuidSettings.aci.toString()).size() > 0;
|
||||
|
||||
if (hasE164Session && hasUuidSession) {
|
||||
Log.w(TAG, "Had a session for both users. Deleting the E164.", true);
|
||||
@@ -3114,7 +3117,7 @@ public class RecipientDatabase extends Database {
|
||||
} else if (hasE164Session && !hasUuidSession) {
|
||||
Log.w(TAG, "Had a session for E164, but not UUID. Re-assigning to the UUID.", true);
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(SessionDatabase.ADDRESS, uuidSettings.uuid.toString());
|
||||
values.put(SessionDatabase.ADDRESS, uuidSettings.aci.toString());
|
||||
db.update(SessionDatabase.TABLE_NAME, values, SessionDatabase.ADDRESS + " = ?", SqlUtil.buildArgs(e164Settings.e164));
|
||||
} else if (!hasE164Session && hasUuidSession) {
|
||||
Log.w(TAG, "Had a session for UUID, but not E164. No action necessary.", true);
|
||||
@@ -3260,7 +3263,7 @@ public class RecipientDatabase extends Database {
|
||||
|
||||
public static class RecipientSettings {
|
||||
private final RecipientId id;
|
||||
private final UUID uuid;
|
||||
private final ACI aci;
|
||||
private final String username;
|
||||
private final String e164;
|
||||
private final String email;
|
||||
@@ -3310,7 +3313,7 @@ public class RecipientDatabase extends Database {
|
||||
private final List<Badge> badges;
|
||||
|
||||
RecipientSettings(@NonNull RecipientId id,
|
||||
@Nullable UUID uuid,
|
||||
@Nullable ACI uuid,
|
||||
@Nullable String username,
|
||||
@Nullable String e164,
|
||||
@Nullable String email,
|
||||
@@ -3355,7 +3358,7 @@ public class RecipientDatabase extends Database {
|
||||
@NonNull List<Badge> badges)
|
||||
{
|
||||
this.id = id;
|
||||
this.uuid = uuid;
|
||||
this.aci = uuid;
|
||||
this.username = username;
|
||||
this.e164 = e164;
|
||||
this.email = email;
|
||||
@@ -3409,8 +3412,8 @@ public class RecipientDatabase extends Database {
|
||||
return id;
|
||||
}
|
||||
|
||||
public @Nullable UUID getUuid() {
|
||||
return uuid;
|
||||
public @Nullable ACI getAci() {
|
||||
return aci;
|
||||
}
|
||||
|
||||
public @Nullable String getUsername() {
|
||||
|
||||
@@ -143,8 +143,8 @@ public class SenderKeySharedDatabase extends Database {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
if (recipient.hasUuid()) {
|
||||
db.delete(TABLE_NAME, ADDRESS + " = ?", SqlUtil.buildArgs(recipient.getUuid().get().toString()));
|
||||
if (recipient.hasAci()) {
|
||||
db.delete(TABLE_NAME, ADDRESS + " = ?", SqlUtil.buildArgs(recipient.requireAci().toString()));
|
||||
} else {
|
||||
Log.w(TAG, "Recipient doesn't have a UUID! " + recipientId);
|
||||
}
|
||||
|
||||
@@ -723,11 +723,11 @@ public class SmsDatabase extends MessageDatabase {
|
||||
|
||||
if (!peerEraIdSameAsPrevious && !Util.isEmpty(peekGroupCallEraId)) {
|
||||
Recipient self = Recipient.self();
|
||||
boolean markRead = peekJoinedUuids.contains(self.requireUuid()) || self.getId().equals(sender);
|
||||
boolean markRead = peekJoinedUuids.contains(self.requireAci().uuid()) || self.getId().equals(sender);
|
||||
|
||||
byte[] updateDetails = GroupCallUpdateDetails.newBuilder()
|
||||
.setEraId(Util.emptyIfNull(peekGroupCallEraId))
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireUuid().toString())
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireAci().toString())
|
||||
.setStartedCallTimestamp(timestamp)
|
||||
.addAllInCallUuids(Stream.of(peekJoinedUuids).map(UUID::toString).toList())
|
||||
.setIsCallFull(isCallFull)
|
||||
@@ -804,7 +804,7 @@ public class SmsDatabase extends MessageDatabase {
|
||||
if (!sameEraId && !Util.isEmpty(messageGroupCallEraId)) {
|
||||
byte[] updateDetails = GroupCallUpdateDetails.newBuilder()
|
||||
.setEraId(Util.emptyIfNull(messageGroupCallEraId))
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireUuid().toString())
|
||||
.setStartedCallUuid(Recipient.resolved(sender).requireAci().toString())
|
||||
.setStartedCallTimestamp(timestamp)
|
||||
.addAllInCallUuids(Collections.emptyList())
|
||||
.setIsCallFull(false)
|
||||
@@ -853,7 +853,7 @@ public class SmsDatabase extends MessageDatabase {
|
||||
}
|
||||
|
||||
GroupCallUpdateDetails groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(record.getBody());
|
||||
boolean containsSelf = peekJoinedUuids.contains(Recipient.self().requireUuid());
|
||||
boolean containsSelf = peekJoinedUuids.contains(Recipient.self().requireAci().uuid());
|
||||
|
||||
sameEraId = groupCallUpdateDetails.getEraId().equals(peekGroupCallEraId) && !Util.isEmpty(peekGroupCallEraId);
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
|
||||
@@ -1446,7 +1447,7 @@ public class ThreadDatabase extends Database {
|
||||
if (threadRecipient.isPushV2Group()) {
|
||||
MessageRecord.InviteAddState inviteAddState = record.getGv2AddInviteState();
|
||||
if (inviteAddState != null) {
|
||||
RecipientId from = RecipientId.from(inviteAddState.getAddedOrInvitedBy(), null);
|
||||
RecipientId from = RecipientId.from(ACI.from(inviteAddState.getAddedOrInvitedBy()), null);
|
||||
if (inviteAddState.isInvited()) {
|
||||
Log.i(TAG, "GV2 invite message request from " + from);
|
||||
return Extra.forGroupV2invite(from, individualRecipientId);
|
||||
|
||||
+11
-12
@@ -10,26 +10,25 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Create a group call update message based on time and joined members.
|
||||
*/
|
||||
public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFactory {
|
||||
private final Context context;
|
||||
private final List<UUID> joinedMembers;
|
||||
private final List<ACI> joinedMembers;
|
||||
private final boolean withTime;
|
||||
private final GroupCallUpdateDetails groupCallUpdateDetails;
|
||||
private final UUID selfUuid;
|
||||
private final ACI selfAci;
|
||||
|
||||
public GroupCallUpdateMessageFactory(@NonNull Context context,
|
||||
@NonNull List<UUID> joinedMembers,
|
||||
@NonNull List<ACI> joinedMembers,
|
||||
boolean withTime,
|
||||
@NonNull GroupCallUpdateDetails groupCallUpdateDetails)
|
||||
{
|
||||
@@ -37,11 +36,11 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa
|
||||
this.joinedMembers = new ArrayList<>(joinedMembers);
|
||||
this.withTime = withTime;
|
||||
this.groupCallUpdateDetails = groupCallUpdateDetails;
|
||||
this.selfUuid = TextSecurePreferences.getLocalUuid(context);
|
||||
this.selfAci = TextSecurePreferences.getLocalAci(context);
|
||||
|
||||
boolean removed = this.joinedMembers.remove(selfUuid);
|
||||
boolean removed = this.joinedMembers.remove(selfAci);
|
||||
if (removed) {
|
||||
this.joinedMembers.add(selfUuid);
|
||||
this.joinedMembers.add(selfAci);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +56,7 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa
|
||||
if (joinedMembers.get(0).toString().equals(groupCallUpdateDetails.getStartedCallUuid())) {
|
||||
return withTime ? context.getString(R.string.MessageRecord_s_started_a_group_call_s, describe(joinedMembers.get(0)), time)
|
||||
: context.getString(R.string.MessageRecord_s_started_a_group_call, describe(joinedMembers.get(0)));
|
||||
} else if (Objects.equals(joinedMembers.get(0), selfUuid)) {
|
||||
} else if (Objects.equals(joinedMembers.get(0), selfAci)) {
|
||||
return withTime ? context.getString(R.string.MessageRecord_you_are_in_the_group_call_s1, time)
|
||||
: context.getString(R.string.MessageRecord_you_are_in_the_group_call);
|
||||
} else {
|
||||
@@ -88,12 +87,12 @@ public class GroupCallUpdateMessageFactory implements UpdateDescription.StringFa
|
||||
}
|
||||
}
|
||||
|
||||
private @NonNull String describe(@NonNull UUID uuid) {
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||
private @NonNull String describe(@NonNull ACI aci) {
|
||||
if (aci.isUnknown()) {
|
||||
return context.getString(R.string.MessageRecord_unknown);
|
||||
}
|
||||
|
||||
Recipient recipient = Recipient.resolved(RecipientId.from(uuid, null));
|
||||
Recipient recipient = Recipient.resolved(RecipientId.from(aci, null));
|
||||
|
||||
if (recipient.isSelf()) {
|
||||
return context.getString(R.string.MessageRecord_you);
|
||||
|
||||
+9
-7
@@ -26,6 +26,7 @@ import org.thoughtcrime.securesms.util.ExpirationUtil;
|
||||
import org.thoughtcrime.securesms.util.StringUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -744,11 +745,12 @@ final class GroupsV2UpdateMessageProducer {
|
||||
interface DescribeMemberStrategy {
|
||||
|
||||
/**
|
||||
* Map a UUID to a string that describes the group member.
|
||||
* Map an ACI to a string that describes the group member.
|
||||
* @param aci
|
||||
*/
|
||||
@NonNull
|
||||
@WorkerThread
|
||||
String describe(@NonNull UUID uuid);
|
||||
String describe(@NonNull ACI aci);
|
||||
}
|
||||
|
||||
private interface StringFactory1Arg {
|
||||
@@ -769,9 +771,9 @@ final class GroupsV2UpdateMessageProducer {
|
||||
@NonNull StringFactory1Arg stringFactory,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
UUID uuid1 = UuidUtil.fromByteStringOrUnknown(uuid1Bytes);
|
||||
ACI aci1 = ACI.fromByteStringOrUnknown(uuid1Bytes);
|
||||
|
||||
return UpdateDescription.mentioning(Collections.singletonList(uuid1), () -> stringFactory.create(descriptionStrategy.describe(uuid1)), iconResource);
|
||||
return UpdateDescription.mentioning(Collections.singletonList(aci1), () -> stringFactory.create(descriptionStrategy.describe(aci1)), iconResource);
|
||||
}
|
||||
|
||||
private UpdateDescription updateDescription(@NonNull ByteString uuid1Bytes,
|
||||
@@ -779,9 +781,9 @@ final class GroupsV2UpdateMessageProducer {
|
||||
@NonNull StringFactory2Args stringFactory,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
UUID uuid1 = UuidUtil.fromByteStringOrUnknown(uuid1Bytes);
|
||||
UUID uuid2 = UuidUtil.fromByteStringOrUnknown(uuid2Bytes);
|
||||
ACI aci1 = ACI.fromByteStringOrUnknown(uuid1Bytes);
|
||||
ACI aci2 = ACI.fromByteStringOrUnknown(uuid2Bytes);
|
||||
|
||||
return UpdateDescription.mentioning(Arrays.asList(uuid1, uuid2), () -> stringFactory.create(descriptionStrategy.describe(uuid1), descriptionStrategy.describe(uuid2)), iconResource);
|
||||
return UpdateDescription.mentioning(Arrays.asList(aci1, aci2), () -> stringFactory.create(descriptionStrategy.describe(aci1), descriptionStrategy.describe(aci2)), iconResource);
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ import org.thoughtcrime.securesms.util.StringUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Function;
|
||||
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -240,7 +241,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
|
||||
private static boolean selfCreatedGroup(@NonNull DecryptedGroupChange change) {
|
||||
return change.getRevision() == 0 &&
|
||||
change.getEditor().equals(UuidUtil.toByteString(Recipient.self().requireUuid()));
|
||||
change.getEditor().equals(UuidUtil.toByteString(Recipient.self().requireAci().uuid()));
|
||||
}
|
||||
|
||||
public static @NonNull UpdateDescription getGv2ChangeDescription(@NonNull Context context, @NonNull String body) {
|
||||
@@ -248,7 +249,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
ShortStringDescriptionStrategy descriptionStrategy = new ShortStringDescriptionStrategy(context);
|
||||
byte[] decoded = Base64.decode(body);
|
||||
DecryptedGroupV2Context decryptedGroupV2Context = DecryptedGroupV2Context.parseFrom(decoded);
|
||||
GroupsV2UpdateMessageProducer updateMessageProducer = new GroupsV2UpdateMessageProducer(context, descriptionStrategy, Recipient.self().getUuid().get());
|
||||
GroupsV2UpdateMessageProducer updateMessageProducer = new GroupsV2UpdateMessageProducer(context, descriptionStrategy, Recipient.self().requireAci().uuid());
|
||||
|
||||
if (decryptedGroupV2Context.hasChange() && (decryptedGroupV2Context.getGroupState().getRevision() != 0 || decryptedGroupV2Context.hasPreviousGroupState())) {
|
||||
return UpdateDescription.concatWithNewLines(updateMessageProducer.describeChanges(decryptedGroupV2Context.getPreviousGroupState(), decryptedGroupV2Context.getChange()));
|
||||
@@ -279,7 +280,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
}
|
||||
|
||||
DecryptedGroup groupState = decryptedGroupV2Context.getGroupState();
|
||||
boolean invited = DecryptedGroupUtil.findPendingByUuid(groupState.getPendingMembersList(), Recipient.self().requireUuid()).isPresent();
|
||||
boolean invited = DecryptedGroupUtil.findPendingByUuid(groupState.getPendingMembersList(), Recipient.self().requireAci().uuid()).isPresent();
|
||||
|
||||
if (decryptedGroupV2Context.hasChange()) {
|
||||
UUID changeEditor = UuidUtil.fromByteStringOrNull(decryptedGroupV2Context.getChange().getEditor());
|
||||
@@ -301,7 +302,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
@NonNull Function<Recipient, String> stringGenerator,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
return UpdateDescription.mentioning(Collections.singletonList(recipient.getUuid().or(UuidUtil.UNKNOWN_UUID)),
|
||||
return UpdateDescription.mentioning(Collections.singletonList(recipient.getAci().or(ACI.UNKNOWN)),
|
||||
() -> stringGenerator.apply(recipient.resolve()),
|
||||
iconResource);
|
||||
}
|
||||
@@ -369,10 +370,11 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
public static @NonNull UpdateDescription getGroupCallUpdateDescription(@NonNull Context context, @NonNull String body, boolean withTime) {
|
||||
GroupCallUpdateDetails groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(body);
|
||||
|
||||
List<UUID> joinedMembers = Stream.of(groupCallUpdateDetails.getInCallUuidsList())
|
||||
.map(UuidUtil::parseOrNull)
|
||||
.withoutNulls()
|
||||
.toList();
|
||||
List<ACI> joinedMembers = Stream.of(groupCallUpdateDetails.getInCallUuidsList())
|
||||
.map(UuidUtil::parseOrNull)
|
||||
.withoutNulls()
|
||||
.map(ACI::from)
|
||||
.toList();
|
||||
|
||||
UpdateDescription.StringFactory stringFactory = new GroupCallUpdateMessageFactory(context, joinedMembers, withTime, groupCallUpdateDetails);
|
||||
|
||||
@@ -407,11 +409,11 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String describe(@NonNull UUID uuid) {
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||
public @NonNull String describe(@NonNull ACI aci) {
|
||||
if (aci.isUnknown()) {
|
||||
return context.getString(R.string.MessageRecord_unknown);
|
||||
}
|
||||
return Recipient.resolved(RecipientId.from(uuid, null)).getDisplayName(context);
|
||||
return Recipient.resolved(RecipientId.from(aci, null)).getDisplayName(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-11
@@ -8,6 +8,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -27,14 +28,14 @@ public final class UpdateDescription {
|
||||
String create();
|
||||
}
|
||||
|
||||
private final Collection<UUID> mentioned;
|
||||
private final StringFactory stringFactory;
|
||||
private final String staticString;
|
||||
private final int lightIconResource;
|
||||
private final int lightTint;
|
||||
private final int darkTint;
|
||||
private final Collection<ACI> mentioned;
|
||||
private final StringFactory stringFactory;
|
||||
private final String staticString;
|
||||
private final int lightIconResource;
|
||||
private final int lightTint;
|
||||
private final int darkTint;
|
||||
|
||||
private UpdateDescription(@NonNull Collection<UUID> mentioned,
|
||||
private UpdateDescription(@NonNull Collection<ACI> mentioned,
|
||||
@Nullable StringFactory stringFactory,
|
||||
@Nullable String staticString,
|
||||
@DrawableRes int iconResource,
|
||||
@@ -59,11 +60,11 @@ public final class UpdateDescription {
|
||||
* @param mentioned UUIDs of recipients that are mentioned in the string.
|
||||
* @param stringFactory The background method for generating the string.
|
||||
*/
|
||||
public static UpdateDescription mentioning(@NonNull Collection<UUID> mentioned,
|
||||
public static UpdateDescription mentioning(@NonNull Collection<ACI> mentioned,
|
||||
@NonNull StringFactory stringFactory,
|
||||
@DrawableRes int iconResource)
|
||||
{
|
||||
return new UpdateDescription(UuidUtil.filterKnown(mentioned),
|
||||
return new UpdateDescription(ACI.filterKnown(mentioned),
|
||||
stringFactory,
|
||||
null,
|
||||
iconResource,
|
||||
@@ -117,7 +118,7 @@ public final class UpdateDescription {
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
public Collection<UUID> getMentioned() {
|
||||
public Collection<ACI> getMentioned() {
|
||||
return mentioned;
|
||||
}
|
||||
|
||||
@@ -148,7 +149,7 @@ public final class UpdateDescription {
|
||||
);
|
||||
}
|
||||
|
||||
Set<UUID> allMentioned = new HashSet<>();
|
||||
Set<ACI> allMentioned = new HashSet<>();
|
||||
|
||||
for (UpdateDescription updateDescription : updateDescriptions) {
|
||||
allMentioned.addAll(updateDescription.getMentioned());
|
||||
|
||||
+3
-3
@@ -72,6 +72,7 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.SignalWebSocket;
|
||||
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.services.DonationsService;
|
||||
import org.whispersystems.signalservice.api.util.CredentialsProvider;
|
||||
import org.whispersystems.signalservice.api.util.SleepTimer;
|
||||
@@ -79,7 +80,6 @@ import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketFactory;
|
||||
import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -359,8 +359,8 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUuid() {
|
||||
return TextSecurePreferences.getLocalUuid(context);
|
||||
public ACI getAci() {
|
||||
return TextSecurePreferences.getLocalAci(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,6 +60,7 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ConflictException;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
@@ -92,7 +93,7 @@ final class GroupManagerV2 {
|
||||
private final GroupsV2Operations groupsV2Operations;
|
||||
private final GroupsV2Authorization authorization;
|
||||
private final GroupsV2StateProcessor groupsV2StateProcessor;
|
||||
private final UUID selfUuid;
|
||||
private final ACI selfAci;
|
||||
private final GroupCandidateHelper groupCandidateHelper;
|
||||
|
||||
GroupManagerV2(@NonNull Context context) {
|
||||
@@ -102,7 +103,7 @@ final class GroupManagerV2 {
|
||||
this.groupsV2Operations = ApplicationDependencies.getGroupsV2Operations();
|
||||
this.authorization = ApplicationDependencies.getGroupsV2Authorization();
|
||||
this.groupsV2StateProcessor = ApplicationDependencies.getGroupsV2StateProcessor();
|
||||
this.selfUuid = Recipient.self().getUuid().get();
|
||||
this.selfAci = Recipient.self().requireAci();
|
||||
this.groupCandidateHelper = new GroupCandidateHelper(context);
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ final class GroupManagerV2 {
|
||||
|
||||
return groupsV2Api.getGroupJoinInfo(groupSecretParams,
|
||||
Optional.fromNullable(password).transform(GroupLinkPassword::serialize),
|
||||
authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -127,7 +128,7 @@ final class GroupManagerV2 {
|
||||
|
||||
GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
|
||||
|
||||
return groupsV2Api.getGroupExternalCredential(authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
return groupsV2Api.getGroupExternalCredential(authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -140,7 +141,7 @@ final class GroupManagerV2 {
|
||||
|
||||
Map<UUID, UuidCiphertext> uuidCipherTexts = new HashMap<>();
|
||||
for (Recipient recipient : recipients) {
|
||||
uuidCipherTexts.put(recipient.requireUuid(), clientZkGroupCipher.encryptUuid(recipient.requireUuid()));
|
||||
uuidCipherTexts.put(recipient.requireAci().uuid(), clientZkGroupCipher.encryptUuid(recipient.requireAci().uuid()));
|
||||
}
|
||||
|
||||
return uuidCipherTexts;
|
||||
@@ -195,7 +196,7 @@ final class GroupManagerV2 {
|
||||
return latest;
|
||||
}
|
||||
|
||||
Optional<DecryptedMember> selfInFullMemberList = DecryptedGroupUtil.findMemberByUuid(latest.getMembersList(), Recipient.self().requireUuid());
|
||||
Optional<DecryptedMember> selfInFullMemberList = DecryptedGroupUtil.findMemberByUuid(latest.getMembersList(), selfAci.uuid());
|
||||
|
||||
if (!selfInFullMemberList.isPresent()) {
|
||||
return latest;
|
||||
@@ -267,7 +268,7 @@ final class GroupManagerV2 {
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient.getId(), true);
|
||||
|
||||
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder(GroupChangeReconstruct.reconstructGroupChange(DecryptedGroup.newBuilder().build(), decryptedGroup))
|
||||
.setEditor(UuidUtil.toByteString(selfUuid))
|
||||
.setEditor(selfAci.toByteString())
|
||||
.build();
|
||||
|
||||
RecipientAndThread recipientAndThread = sendGroupUpdate(masterKey, new GroupMutation(null, groupChange, decryptedGroup), null);
|
||||
@@ -312,7 +313,7 @@ final class GroupManagerV2 {
|
||||
groupCandidates = GroupCandidate.withoutProfileKeyCredentials(groupCandidates);
|
||||
}
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createModifyGroupMembershipChange(groupCandidates, selfUuid));
|
||||
return commitChangeWithConflictResolution(groupOperations.createModifyGroupMembershipChange(groupCandidates, selfAci.uuid()));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -356,7 +357,7 @@ final class GroupManagerV2 {
|
||||
}
|
||||
|
||||
if (avatarChanged) {
|
||||
String cdnKey = avatarBytes != null ? groupsV2Api.uploadAvatar(avatarBytes, groupSecretParams, authorization.getAuthorizationForToday(selfUuid, groupSecretParams))
|
||||
String cdnKey = avatarBytes != null ? groupsV2Api.uploadAvatar(avatarBytes, groupSecretParams, authorization.getAuthorizationForToday(selfAci, groupSecretParams))
|
||||
: "";
|
||||
change.setModifyAvatar(GroupChange.Actions.ModifyAvatarAction.newBuilder()
|
||||
.setAvatar(cdnKey));
|
||||
@@ -387,7 +388,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Set<UUID> uuids = Stream.of(recipientIds)
|
||||
.map(r -> Recipient.resolved(r).getUuid().get())
|
||||
.map(r -> Recipient.resolved(r).requireAci().uuid())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createApproveGroupJoinRequest(uuids));
|
||||
@@ -398,7 +399,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Set<UUID> uuids = Stream.of(recipientIds)
|
||||
.map(r -> Recipient.resolved(r).getUuid().get())
|
||||
.map(r -> Recipient.resolved(r).requireAci().uuid())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createRefuseGroupJoinRequest(uuids));
|
||||
@@ -410,7 +411,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.getUuid().get(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT));
|
||||
return commitChangeWithConflictResolution(groupOperations.createChangeMemberRole(recipient.requireAci().uuid(), admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -420,7 +421,7 @@ final class GroupManagerV2 {
|
||||
Recipient self = Recipient.self();
|
||||
GroupDatabase.GroupRecord groupRecord = groupDatabase.getGroup(groupId).get();
|
||||
List<DecryptedPendingMember> pendingMembersList = groupRecord.requireV2GroupProperties().getDecryptedGroup().getPendingMembersList();
|
||||
Optional<DecryptedPendingMember> selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfUuid);
|
||||
Optional<DecryptedPendingMember> selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfAci.uuid());
|
||||
|
||||
if (selfPendingMember.isPresent()) {
|
||||
try {
|
||||
@@ -439,7 +440,7 @@ final class GroupManagerV2 {
|
||||
{
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.getUuid().get())));
|
||||
return commitChangeWithConflictResolution(groupOperations.createRemoveMembersChange(Collections.singleton(recipient.requireAci().uuid())));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -447,9 +448,9 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupNotAMemberException, GroupInsufficientRightsException, IOException
|
||||
{
|
||||
Recipient self = Recipient.self();
|
||||
List<UUID> newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).getUuid().get()).toList();
|
||||
List<UUID> newAdminRecipients = Stream.of(newAdmins).map(id -> Recipient.resolved(id).requireAci().uuid()).toList();
|
||||
|
||||
return commitChangeWithConflictResolution(groupOperations.createLeaveAndPromoteMembersToAdmin(self.getUuid().get(),
|
||||
return commitChangeWithConflictResolution(groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.uuid(),
|
||||
newAdminRecipients));
|
||||
}
|
||||
|
||||
@@ -459,7 +460,7 @@ final class GroupManagerV2 {
|
||||
{
|
||||
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
|
||||
DecryptedGroup group = groupDatabase.requireGroup(groupId).requireV2GroupProperties().getDecryptedGroup();
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfUuid);
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfAci.uuid());
|
||||
|
||||
if (!selfInGroup.isPresent()) {
|
||||
Log.w(TAG, "Self not in group " + groupId);
|
||||
@@ -489,7 +490,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, GroupInsufficientRightsException, IOException, GroupNotAMemberException
|
||||
{
|
||||
DecryptedGroup group = groupDatabase.requireGroup(groupId).requireV2GroupProperties().getDecryptedGroup();
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), Recipient.self().getUuid().get());
|
||||
Optional<DecryptedMember> selfInGroup = DecryptedGroupUtil.findMemberByUuid(group.getMembersList(), selfAci.uuid());
|
||||
|
||||
if (selfInGroup.isPresent()) {
|
||||
Log.w(TAG, "Self already in group");
|
||||
@@ -553,7 +554,7 @@ final class GroupManagerV2 {
|
||||
private @NonNull GroupManager.GroupActionResult commitChangeWithConflictResolution(@NonNull GroupChange.Actions.Builder change)
|
||||
throws GroupChangeFailedException, GroupNotAMemberException, GroupInsufficientRightsException, IOException
|
||||
{
|
||||
change.setSourceUuid(UuidUtil.toByteString(Recipient.self().getUuid().get()));
|
||||
change.setSourceUuid(UuidUtil.toByteString(selfAci.uuid()));
|
||||
|
||||
for (int attempt = 0; attempt < 5; attempt++) {
|
||||
try {
|
||||
@@ -602,7 +603,7 @@ final class GroupManagerV2 {
|
||||
GroupChange.Actions changeActions = change.build();
|
||||
|
||||
return GroupChangeUtil.resolveConflict(groupUpdateResult.getLatestServer(),
|
||||
groupOperations.decryptChange(changeActions, selfUuid),
|
||||
groupOperations.decryptChange(changeActions, selfAci.uuid()),
|
||||
changeActions);
|
||||
} catch (VerificationFailedException | InvalidGroupStateException ex) {
|
||||
throw new GroupChangeFailedException(ex);
|
||||
@@ -622,7 +623,7 @@ final class GroupManagerV2 {
|
||||
|
||||
try {
|
||||
previousGroupState = v2GroupProperties.getDecryptedGroup();
|
||||
decryptedChange = groupOperations.decryptChange(changeActions, selfUuid);
|
||||
decryptedChange = groupOperations.decryptChange(changeActions, selfAci.uuid());
|
||||
decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange);
|
||||
} catch (VerificationFailedException | InvalidGroupStateException | NotAbleToApplyGroupV2ChangeException e) {
|
||||
Log.w(TAG, e);
|
||||
@@ -644,7 +645,7 @@ final class GroupManagerV2 {
|
||||
throws GroupNotAMemberException, GroupChangeFailedException, IOException, GroupInsufficientRightsException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfUuid, groupSecretParams), Optional.absent());
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfAci, groupSecretParams), Optional.absent());
|
||||
} catch (NotInGroupException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new GroupNotAMemberException(e);
|
||||
@@ -727,9 +728,9 @@ final class GroupManagerV2 {
|
||||
disappearingMessageTimerSeconds);
|
||||
|
||||
try {
|
||||
groupsV2Api.putNewGroup(newGroup, authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
groupsV2Api.putNewGroup(newGroup, authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
|
||||
DecryptedGroup decryptedGroup = groupsV2Api.getGroup(groupSecretParams, ApplicationDependencies.getGroupsV2Authorization().getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
DecryptedGroup decryptedGroup = groupsV2Api.getGroup(groupSecretParams, ApplicationDependencies.getGroupsV2Authorization().getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
if (decryptedGroup == null) {
|
||||
throw new GroupChangeFailedException();
|
||||
}
|
||||
@@ -922,7 +923,7 @@ final class GroupManagerV2 {
|
||||
.setRevision(GroupsV2StateProcessor.PLACEHOLDER_REVISION);
|
||||
|
||||
Recipient self = Recipient.self();
|
||||
ByteString selfUuid = UuidUtil.toByteString(self.requireUuid());
|
||||
ByteString selfUuid = selfAci.toByteString();
|
||||
ByteString profileKey = ByteString.copyFrom(Objects.requireNonNull(self.getProfileKey()));
|
||||
|
||||
if (requestToJoin) {
|
||||
@@ -956,7 +957,7 @@ final class GroupManagerV2 {
|
||||
GroupChange.Actions.Builder change = requestToJoin ? groupOperations.createGroupJoinRequest(profileKeyCredential)
|
||||
: groupOperations.createGroupJoinDirect(profileKeyCredential);
|
||||
|
||||
change.setSourceUuid(UuidUtil.toByteString(Recipient.self().getUuid().get()));
|
||||
change.setSourceUuid(selfAci.toByteString());
|
||||
|
||||
return commitJoinChangeWithConflictResolution(currentRevision, change);
|
||||
}
|
||||
@@ -1000,7 +1001,7 @@ final class GroupManagerV2 {
|
||||
throws GroupChangeFailedException, IOException, GroupLinkNotActiveException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfUuid, groupSecretParams), Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
|
||||
return groupsV2Api.patchGroup(change, authorization.getAuthorizationForToday(selfAci, groupSecretParams), Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
|
||||
} catch (NotInGroupException | VerificationFailedException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new GroupChangeFailedException(e);
|
||||
@@ -1044,7 +1045,7 @@ final class GroupManagerV2 {
|
||||
throws IOException, VerificationFailedException, InvalidGroupStateException
|
||||
{
|
||||
try {
|
||||
groupsV2Api.getGroup(groupSecretParams, authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
groupsV2Api.getGroup(groupSecretParams, authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
return true;
|
||||
} catch (NotInGroupException ex) {
|
||||
return false;
|
||||
@@ -1055,7 +1056,7 @@ final class GroupManagerV2 {
|
||||
void cancelJoinRequest()
|
||||
throws GroupChangeFailedException, IOException
|
||||
{
|
||||
Set<UUID> uuids = Collections.singleton(Recipient.self().getUuid().get());
|
||||
Set<UUID> uuids = Collections.singleton(selfAci.uuid());
|
||||
|
||||
GroupChange signedGroupChange;
|
||||
try {
|
||||
@@ -1158,7 +1159,7 @@ final class GroupManagerV2 {
|
||||
|
||||
private static @NonNull List<RecipientId> getPendingMemberRecipientIds(@NonNull List<DecryptedPendingMember> newPendingMembersList) {
|
||||
return Stream.of(DecryptedGroupUtil.pendingToUuidList(newPendingMembersList))
|
||||
.map(uuid-> RecipientId.from(uuid,null))
|
||||
.map(uuid -> RecipientId.from(ACI.from(uuid), null))
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.DecryptedGroupV2
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
|
||||
@@ -85,27 +86,26 @@ public final class GroupProtoUtil {
|
||||
|
||||
@WorkerThread
|
||||
public static Recipient uuidByteStringToRecipient(@NonNull Context context, @NonNull ByteString uuidByteString) {
|
||||
UUID uuid = UUIDUtil.deserialize(uuidByteString.toByteArray());
|
||||
ACI aci = ACI.fromByteString(uuidByteString);
|
||||
|
||||
if (uuid.equals(GroupsV2Operations.UNKNOWN_UUID)) {
|
||||
if (aci.isUnknown()) {
|
||||
return Recipient.UNKNOWN;
|
||||
}
|
||||
|
||||
return Recipient.externalPush(context, uuid, null, false);
|
||||
return Recipient.externalPush(context, aci, null, false);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static @NonNull RecipientId uuidByteStringToRecipientId(@NonNull ByteString uuidByteString) {
|
||||
UUID uuid = UUIDUtil.deserialize(uuidByteString.toByteArray());
|
||||
ACI aci = ACI.fromByteString(uuidByteString);
|
||||
|
||||
if (uuid.equals(GroupsV2Operations.UNKNOWN_UUID)) {
|
||||
if (aci.isUnknown()) {
|
||||
return RecipientId.UNKNOWN;
|
||||
}
|
||||
|
||||
return RecipientId.from(uuid, null);
|
||||
return RecipientId.from(aci, null);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isMember(@NonNull UUID uuid, @NonNull List<DecryptedMember> membersList) {
|
||||
ByteString uuidBytes = UuidUtil.toByteString(uuid);
|
||||
|
||||
|
||||
@@ -232,10 +232,10 @@ public final class GroupsV1MigrationUtil {
|
||||
* True if the user meets all the requirements to be auto-migrated, otherwise false.
|
||||
*/
|
||||
public static boolean isAutoMigratable(@NonNull Recipient recipient) {
|
||||
return recipient.hasUuid() &&
|
||||
recipient.getGroupsV2Capability() == Recipient.Capability.SUPPORTED &&
|
||||
return recipient.hasAci() &&
|
||||
recipient.getGroupsV2Capability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.getGroupsV1MigrationCapability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED &&
|
||||
recipient.getRegistered() == RecipientDatabase.RegisteredState.REGISTERED &&
|
||||
recipient.getProfileKey() != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.signal.zkgroup.groups.GroupSecretParams;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NoCredentialForRedemptionTimeException;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@@ -27,7 +28,7 @@ public final class GroupsV2Authorization {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public GroupsV2AuthorizationString getAuthorizationForToday(@NonNull UUID self,
|
||||
public GroupsV2AuthorizationString getAuthorizationForToday(@NonNull ACI self,
|
||||
@NonNull GroupSecretParams groupSecretParams)
|
||||
throws IOException, VerificationFailedException
|
||||
{
|
||||
@@ -65,7 +66,7 @@ public final class GroupsV2Authorization {
|
||||
return (int) TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private GroupsV2AuthorizationString getAuthorization(UUID self,
|
||||
private GroupsV2AuthorizationString getAuthorization(ACI self,
|
||||
GroupSecretParams groupSecretParams,
|
||||
Map<Integer, AuthCredentialResponse> credentials,
|
||||
int today)
|
||||
|
||||
@@ -86,7 +86,7 @@ public final class GroupsV2CapabilityChecker {
|
||||
}
|
||||
}
|
||||
|
||||
if (!member.hasUuid()) {
|
||||
if (!member.hasAci()) {
|
||||
noUuidCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -108,7 +109,7 @@ public final class LiveGroup {
|
||||
|
||||
return Stream.of(requestingMembersList)
|
||||
.map(requestingMember -> {
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), UuidUtil.fromByteString(requestingMember.getUuid()), null, false);
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), ACI.fromByteString(requestingMember.getUuid()), null, false);
|
||||
return new GroupMemberEntry.RequestingMember(recipient, selfAdmin);
|
||||
})
|
||||
.toList();
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ final class PendingMemberInvitesRepository {
|
||||
List<DecryptedPendingMember> pendingMembersList = decryptedGroup.getPendingMembersList();
|
||||
List<SinglePendingMemberInvitedByYou> byMe = new ArrayList<>(pendingMembersList.size());
|
||||
List<MultiplePendingMembersInvitedByAnother> byOthers = new ArrayList<>(pendingMembersList.size());
|
||||
ByteString self = ByteString.copyFrom(UUIDUtil.serialize(Recipient.self().getUuid().get()));
|
||||
ByteString self = Recipient.self().requireAci().toByteString();
|
||||
boolean selfIsAdmin = v2GroupProperties.isAdmin(Recipient.self());
|
||||
|
||||
Stream.of(pendingMembersList)
|
||||
|
||||
+2
-3
@@ -20,7 +20,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
@@ -96,8 +95,8 @@ final class GroupsV1MigrationRepository {
|
||||
group = group.fresh();
|
||||
|
||||
List<Recipient> ineligible = Stream.of(group.getParticipants())
|
||||
.filter(r -> !r.hasUuid() ||
|
||||
r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED ||
|
||||
.filter(r -> !r.hasAci() ||
|
||||
r.getGroupsV2Capability() != Recipient.Capability.SUPPORTED ||
|
||||
r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED ||
|
||||
r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED)
|
||||
.toList();
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
@@ -47,13 +48,13 @@ public final class GroupCandidateHelper {
|
||||
{
|
||||
final Recipient recipient = Recipient.resolved(recipientId);
|
||||
|
||||
UUID uuid = recipient.getUuid().orNull();
|
||||
if (uuid == null) {
|
||||
ACI aci = recipient.getAci().orNull();
|
||||
if (aci == null) {
|
||||
throw new AssertionError("Non UUID members should have need detected by now");
|
||||
}
|
||||
|
||||
Optional<ProfileKeyCredential> profileKeyCredential = Optional.fromNullable(recipient.getProfileKeyCredential());
|
||||
GroupCandidate candidate = new GroupCandidate(uuid, profileKeyCredential);
|
||||
GroupCandidate candidate = new GroupCandidate(aci.uuid(), profileKeyCredential);
|
||||
|
||||
if (!candidate.hasProfileKeyCredential()) {
|
||||
ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey());
|
||||
@@ -61,7 +62,7 @@ public final class GroupCandidateHelper {
|
||||
if (profileKey != null) {
|
||||
Log.i(TAG, String.format("No profile key credential on recipient %s, fetching", recipient.getId()));
|
||||
|
||||
Optional<ProfileKeyCredential> profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(uuid, profileKey, Locale.getDefault());
|
||||
Optional<ProfileKeyCredential> profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(aci, profileKey, Locale.getDefault());
|
||||
|
||||
if (profileKeyCredentialOptional.isPresent()) {
|
||||
boolean updatedProfileKey = recipientDatabase.setProfileKeyCredential(recipient.getId(), profileKey, profileKeyCredentialOptional.get());
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedRequestingMember;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -30,8 +31,8 @@ public final class ProfileKeySet {
|
||||
|
||||
private static final String TAG = Log.tag(ProfileKeySet.class);
|
||||
|
||||
private final Map<UUID, ProfileKey> profileKeys = new LinkedHashMap<>();
|
||||
private final Map<UUID, ProfileKey> authoritativeProfileKeys = new LinkedHashMap<>();
|
||||
private final Map<ACI, ProfileKey> profileKeys = new LinkedHashMap<>();
|
||||
private final Map<ACI, ProfileKey> authoritativeProfileKeys = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Add new profile keys from a group change.
|
||||
@@ -96,20 +97,20 @@ public final class ProfileKeySet {
|
||||
}
|
||||
|
||||
if (memberUuid.equals(changeSource)) {
|
||||
authoritativeProfileKeys.put(memberUuid, profileKey);
|
||||
profileKeys.remove(memberUuid);
|
||||
authoritativeProfileKeys.put(ACI.from(memberUuid), profileKey);
|
||||
profileKeys.remove(ACI.from(memberUuid));
|
||||
} else {
|
||||
if (!authoritativeProfileKeys.containsKey(memberUuid)) {
|
||||
profileKeys.put(memberUuid, profileKey);
|
||||
if (!authoritativeProfileKeys.containsKey(ACI.from(memberUuid))) {
|
||||
profileKeys.put(ACI.from(memberUuid), profileKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<UUID, ProfileKey> getProfileKeys() {
|
||||
public Map<ACI, ProfileKey> getProfileKeys() {
|
||||
return profileKeys;
|
||||
}
|
||||
|
||||
public Map<UUID, ProfileKey> getAuthoritativeProfileKeys() {
|
||||
public Map<ACI, ProfileKey> getAuthoritativeProfileKeys() {
|
||||
return authoritativeProfileKeys;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-17
@@ -49,6 +49,7 @@ import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
||||
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.GroupNotFoundException;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.NotInGroupException;
|
||||
@@ -206,7 +207,7 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
|
||||
if (inputGroupState == null) {
|
||||
if (localState != null && DecryptedGroupUtil.isPendingOrRequesting(localState, Recipient.self().getUuid().get())) {
|
||||
if (localState != null && DecryptedGroupUtil.isPendingOrRequesting(localState, Recipient.self().requireAci().uuid())) {
|
||||
Log.w(TAG, "Unable to query server for group " + groupId + " server says we're not in group, but we think we are a pending or requesting member");
|
||||
} else {
|
||||
Log.w(TAG, "Unable to query server for group " + groupId + " server says we're not in group, inserting leave message");
|
||||
@@ -250,7 +251,7 @@ public final class GroupsV2StateProcessor {
|
||||
throws IOException, GroupNotAMemberException, GroupDoesNotExistException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams));
|
||||
return groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireAci(), groupSecretParams));
|
||||
} catch (GroupNotFoundException e) {
|
||||
throw new GroupDoesNotExistException(e);
|
||||
} catch (NotInGroupException e) {
|
||||
@@ -265,7 +266,7 @@ public final class GroupsV2StateProcessor {
|
||||
throws IOException, GroupNotAMemberException, GroupDoesNotExistException
|
||||
{
|
||||
try {
|
||||
return groupsV2Api.getGroupHistory(groupSecretParams, revision, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireUuid(), groupSecretParams))
|
||||
return groupsV2Api.getGroupHistory(groupSecretParams, revision, groupsV2Authorization.getAuthorizationForToday(Recipient.self().requireAci(), groupSecretParams))
|
||||
.get(0)
|
||||
.getGroup()
|
||||
.orNull();
|
||||
@@ -285,7 +286,7 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
|
||||
Recipient groupRecipient = Recipient.externalGroupExact(context, groupId);
|
||||
UUID selfUuid = Recipient.self().getUuid().get();
|
||||
UUID selfUuid = Recipient.self().requireAci().uuid();
|
||||
DecryptedGroup decryptedGroup = groupDatabase.requireGroup(groupId)
|
||||
.requireV2GroupProperties()
|
||||
.getDecryptedGroup();
|
||||
@@ -359,7 +360,7 @@ public final class GroupsV2StateProcessor {
|
||||
@NonNull DecryptedGroup newLocalState)
|
||||
{
|
||||
if (inputGroupState.getLocalState() != null) {
|
||||
boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), Recipient.self().getUuid().get()).isPresent();
|
||||
boolean wasAMemberAlready = DecryptedGroupUtil.findMemberByUuid(inputGroupState.getLocalState().getMembersList(), Recipient.self().requireAci().uuid()).isPresent();
|
||||
|
||||
if (wasAMemberAlready) {
|
||||
Log.i(TAG, "Skipping profile sharing detection as was already a full member before update");
|
||||
@@ -367,7 +368,7 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
Optional<DecryptedMember> selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), Recipient.self().getUuid().get());
|
||||
Optional<DecryptedMember> selfAsMemberOptional = DecryptedGroupUtil.findMemberByUuid(newLocalState.getMembersList(), Recipient.self().requireAci().uuid());
|
||||
|
||||
if (selfAsMemberOptional.isPresent()) {
|
||||
DecryptedMember selfAsMember = selfAsMemberOptional.get();
|
||||
@@ -378,7 +379,7 @@ public final class GroupsV2StateProcessor {
|
||||
.filter(c -> c != null && c.getRevision() == revisionJoinedAt)
|
||||
.findFirst()
|
||||
.map(c -> Optional.fromNullable(UuidUtil.fromByteStringOrNull(c.getEditor()))
|
||||
.transform(a -> Recipient.externalPush(context, UuidUtil.fromByteStringOrNull(c.getEditor()), null, false)))
|
||||
.transform(a -> Recipient.externalPush(context, ACI.fromByteStringOrNull(c.getEditor()), null, false)))
|
||||
.orElse(Optional.absent());
|
||||
|
||||
if (addedByOptional.isPresent()) {
|
||||
@@ -446,33 +447,33 @@ public final class GroupsV2StateProcessor {
|
||||
private @NonNull GlobalGroupState queryServer(@Nullable DecryptedGroup localState, boolean latestOnly)
|
||||
throws IOException, GroupNotAMemberException
|
||||
{
|
||||
UUID selfUuid = Recipient.self().getUuid().get();
|
||||
ACI selfAci = Recipient.self().requireAci();
|
||||
DecryptedGroup latestServerGroup;
|
||||
List<ServerGroupLogEntry> history;
|
||||
|
||||
try {
|
||||
latestServerGroup = groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams));
|
||||
latestServerGroup = groupsV2Api.getGroup(groupSecretParams, groupsV2Authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
} catch (NotInGroupException | GroupNotFoundException e) {
|
||||
throw new GroupNotAMemberException(e);
|
||||
} catch (VerificationFailedException | InvalidGroupStateException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
if (latestOnly || !GroupProtoUtil.isMember(selfUuid, latestServerGroup.getMembersList())) {
|
||||
if (latestOnly || !GroupProtoUtil.isMember(selfAci.uuid(), latestServerGroup.getMembersList())) {
|
||||
history = Collections.singletonList(new ServerGroupLogEntry(latestServerGroup, null));
|
||||
} else {
|
||||
int revisionWeWereAdded = GroupProtoUtil.findRevisionWeWereAdded(latestServerGroup, selfUuid);
|
||||
int revisionWeWereAdded = GroupProtoUtil.findRevisionWeWereAdded(latestServerGroup, selfAci.uuid());
|
||||
int logsNeededFrom = localState != null ? Math.max(localState.getRevision(), revisionWeWereAdded) : revisionWeWereAdded;
|
||||
|
||||
history = getFullMemberHistory(selfUuid, logsNeededFrom);
|
||||
history = getFullMemberHistory(selfAci, logsNeededFrom);
|
||||
}
|
||||
|
||||
return new GlobalGroupState(localState, history);
|
||||
}
|
||||
|
||||
private List<ServerGroupLogEntry> getFullMemberHistory(@NonNull UUID selfUuid, int logsNeededFromRevision) throws IOException {
|
||||
private List<ServerGroupLogEntry> getFullMemberHistory(@NonNull ACI selfAci, int logsNeededFromRevision) throws IOException {
|
||||
try {
|
||||
Collection<DecryptedGroupHistoryEntry> groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFromRevision, groupsV2Authorization.getAuthorizationForToday(selfUuid, groupSecretParams));
|
||||
Collection<DecryptedGroupHistoryEntry> groupStatesFromRevision = groupsV2Api.getGroupHistory(groupSecretParams, logsNeededFromRevision, groupsV2Authorization.getAuthorizationForToday(selfAci, groupSecretParams));
|
||||
ArrayList<ServerGroupLogEntry> history = new ArrayList<>(groupStatesFromRevision.size());
|
||||
boolean ignoreServerChanges = SignalStore.internalValues().gv2IgnoreServerChanges();
|
||||
|
||||
@@ -496,9 +497,9 @@ public final class GroupsV2StateProcessor {
|
||||
}
|
||||
|
||||
private void storeMessage(@NonNull DecryptedGroupV2Context decryptedGroupV2Context, long timestamp) {
|
||||
Optional<UUID> editor = getEditor(decryptedGroupV2Context);
|
||||
Optional<ACI> editor = getEditor(decryptedGroupV2Context).transform(ACI::from);
|
||||
|
||||
boolean outgoing = !editor.isPresent() || Recipient.self().requireUuid().equals(editor.get());
|
||||
boolean outgoing = !editor.isPresent() || Recipient.self().requireAci().equals(editor.get());
|
||||
|
||||
if (outgoing) {
|
||||
try {
|
||||
@@ -536,7 +537,7 @@ public final class GroupsV2StateProcessor {
|
||||
if (changeEditor.isPresent()) {
|
||||
return changeEditor;
|
||||
} else {
|
||||
Optional<DecryptedPendingMember> pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), Recipient.self().requireUuid());
|
||||
Optional<DecryptedPendingMember> pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), Recipient.self().requireAci().uuid());
|
||||
if (pendingByUuid.isPresent()) {
|
||||
return Optional.fromNullable(UuidUtil.fromByteStringOrNull(pendingByUuid.get().getAddedByUuid()));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NoCredentialForRedemptionTimeException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
@@ -71,7 +70,7 @@ public class GroupV1MigrationJob extends BaseJob {
|
||||
public static void enqueueRoutineMigrationsIfNecessary(@NonNull Application application) {
|
||||
if (!SignalStore.registrationValues().isRegistrationComplete() ||
|
||||
!TextSecurePreferences.isPushRegistered(application) ||
|
||||
TextSecurePreferences.getLocalUuid(application) == null)
|
||||
TextSecurePreferences.getLocalAci(application) == null)
|
||||
{
|
||||
Log.i(TAG, "Registration not complete. Skipping.");
|
||||
return;
|
||||
|
||||
@@ -105,7 +105,7 @@ public class MmsDownloadJob extends BaseJob {
|
||||
|
||||
@Override
|
||||
public void onRun() {
|
||||
if (TextSecurePreferences.getLocalUuid(context) == null && TextSecurePreferences.getLocalNumber(context) == null) {
|
||||
if (TextSecurePreferences.getLocalAci(context) == null && TextSecurePreferences.getLocalNumber(context) == null) {
|
||||
throw new NotReadyException();
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public class MultiDeviceBlockedUpdateJob extends BaseJob {
|
||||
while ((recipient = reader.getNext()) != null) {
|
||||
if (recipient.isPushGroup()) {
|
||||
blockedGroups.add(recipient.requireGroupId().getDecodedId());
|
||||
} else if (recipient.isMaybeRegistered() && (recipient.hasUuid() || recipient.hasE164())) {
|
||||
} else if (recipient.isMaybeRegistered() && (recipient.hasAci() || recipient.hasE164())) {
|
||||
blockedIndividuals.add(RecipientUtil.toSignalServiceAddress(context, recipient));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.OutgoingPaymentMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
|
||||
|
||||
@@ -88,9 +89,9 @@ public final class MultiDeviceOutgoingPaymentSyncJob extends BaseJob {
|
||||
|
||||
boolean defrag = payment.isDefrag();
|
||||
|
||||
Optional<UUID> uuid;
|
||||
Optional<SignalServiceAddress> uuid;
|
||||
if (!defrag && payment.getPayee().hasRecipientId()) {
|
||||
uuid = Optional.of(Recipient.resolved(payment.getPayee().requireRecipientId()).requireUuid());
|
||||
uuid = Optional.of(new SignalServiceAddress(Recipient.resolved(payment.getPayee().requireRecipientId()).requireAci()));
|
||||
} else {
|
||||
uuid = Optional.absent();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
@@ -73,8 +74,8 @@ public final class PushGroupSilentUpdateSendJob extends BaseJob {
|
||||
|
||||
Set<RecipientId> recipients = Stream.concat(Stream.of(memberUuids), Stream.of(pendingUuids))
|
||||
.filter(uuid -> !UuidUtil.UNKNOWN_UUID.equals(uuid))
|
||||
.filter(uuid -> !Recipient.self().getUuid().get().equals(uuid))
|
||||
.map(uuid -> Recipient.externalPush(context, uuid, null, false))
|
||||
.filter(uuid -> !Recipient.self().requireAci().uuid().equals(uuid))
|
||||
.map(uuid -> Recipient.externalPush(context, ACI.from(uuid), null, false))
|
||||
.filter(recipient -> recipient.getRegistered() != RecipientDatabase.RegisteredState.NOT_REGISTERED)
|
||||
.map(Recipient::getId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
@@ -226,7 +226,7 @@ public class PushMediaSendJob extends PushSendJob {
|
||||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.build();
|
||||
|
||||
if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid())) {
|
||||
if (Util.equals(TextSecurePreferences.getLocalAci(context), address.getAci())) {
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess);
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.annimon.stream.Stream;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
|
||||
import org.signal.libsignal.metadata.certificate.SenderCertificate;
|
||||
@@ -43,7 +42,6 @@ import org.thoughtcrime.securesms.net.NotPushRegisteredException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.registration.PushChallengeRequest;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
@@ -51,11 +49,9 @@ import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.Hex;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||
@@ -68,10 +64,7 @@ import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
||||
import org.whispersystems.signalservice.internal.push.ProofRequiredResponse;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -416,7 +409,7 @@ public abstract class PushSendJob extends SendJob {
|
||||
|
||||
List<SignalServiceDataMessage.Mention> getMentionsFor(@NonNull List<Mention> mentions) {
|
||||
return Stream.of(mentions)
|
||||
.map(m -> new SignalServiceDataMessage.Mention(Recipient.resolved(m.getRecipientId()).requireUuid(), m.getStart(), m.getLength()))
|
||||
.map(m -> new SignalServiceDataMessage.Mention(Recipient.resolved(m.getRecipientId()).requireAci(), m.getStart(), m.getLength()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -454,7 +447,7 @@ public abstract class PushSendJob extends SendJob {
|
||||
}
|
||||
|
||||
protected SignalServiceSyncMessage buildSelfSendSyncMessage(@NonNull Context context, @NonNull SignalServiceDataMessage message, Optional<UnidentifiedAccessPair> syncAccess) {
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalUuid(context), TextSecurePreferences.getLocalNumber(context));
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalAci(context), TextSecurePreferences.getLocalNumber(context));
|
||||
SentTranscriptMessage transcript = new SentTranscriptMessage(Optional.of(localAddress),
|
||||
message.getTimestamp(),
|
||||
message,
|
||||
|
||||
@@ -188,7 +188,7 @@ public class PushTextSendJob extends PushSendJob {
|
||||
.asEndSessionMessage(message.isEndSession())
|
||||
.build();
|
||||
|
||||
if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid())) {
|
||||
if (Util.equals(TextSecurePreferences.getLocalAci(context), address.getAci())) {
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, textSecureMessage, syncAccess);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -16,9 +15,7 @@ import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCredential;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.badges.Badges;
|
||||
import org.thoughtcrime.securesms.badges.models.Badge;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
@@ -38,7 +35,6 @@ import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.ProfileUtil;
|
||||
import org.thoughtcrime.securesms.util.ScreenDensity;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
@@ -51,6 +47,7 @@ import org.whispersystems.signalservice.api.crypto.InvalidCiphertextException;
|
||||
import org.whispersystems.signalservice.api.crypto.ProfileCipher;
|
||||
import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.services.ProfileService;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
|
||||
@@ -62,7 +59,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
@@ -175,7 +171,7 @@ public class RetrieveProfileJob extends BaseJob {
|
||||
public static void enqueueRoutineFetchIfNecessary(Application application) {
|
||||
if (!SignalStore.registrationValues().isRegistrationComplete() ||
|
||||
!TextSecurePreferences.isPushRegistered(application) ||
|
||||
TextSecurePreferences.getLocalUuid(application) == null)
|
||||
TextSecurePreferences.getLocalAci(application) == null)
|
||||
{
|
||||
Log.i(TAG, "Registration not complete. Skipping.");
|
||||
return;
|
||||
@@ -293,11 +289,11 @@ public class RetrieveProfileJob extends BaseJob {
|
||||
Set<RecipientId> success = SetUtil.difference(recipientIds, operationState.retries);
|
||||
recipientDatabase.markProfilesFetched(success, System.currentTimeMillis());
|
||||
|
||||
Map<RecipientId, String> newlyRegistered = Stream.of(operationState.profiles)
|
||||
.map(Pair::first)
|
||||
.filterNot(Recipient::isRegistered)
|
||||
.collect(Collectors.toMap(Recipient::getId,
|
||||
r -> r.getUuid().transform(UUID::toString).orNull()));
|
||||
Map<RecipientId, ACI> newlyRegistered = Stream.of(operationState.profiles)
|
||||
.map(Pair::first)
|
||||
.filterNot(Recipient::isRegistered)
|
||||
.collect(Collectors.toMap(Recipient::getId,
|
||||
r -> r.getAci().orNull()));
|
||||
|
||||
if (operationState.unregistered.size() > 0 || newlyRegistered.size() > 0) {
|
||||
Log.i(TAG, "Marking " + newlyRegistered.size() + " users as registered and " + operationState.unregistered.size() + " users as unregistered.");
|
||||
|
||||
@@ -89,7 +89,7 @@ public class SmsReceiveJob extends BaseJob {
|
||||
public void onRun() throws MigrationPendingException, RetryLaterException {
|
||||
Optional<IncomingTextMessage> message = assembleMessageFragments(pdus, subscriptionId);
|
||||
|
||||
if (TextSecurePreferences.getLocalUuid(context) == null && TextSecurePreferences.getLocalNumber(context) == null) {
|
||||
if (TextSecurePreferences.getLocalAci(context) == null && TextSecurePreferences.getLocalNumber(context) == null) {
|
||||
Log.i(TAG, "Received an SMS before we're registered...");
|
||||
|
||||
if (message.isPresent()) {
|
||||
|
||||
@@ -22,7 +22,7 @@ public final class LogSectionCapabilities implements LogSection {
|
||||
return "Unregistered";
|
||||
}
|
||||
|
||||
if (TextSecurePreferences.getLocalNumber(context) == null || TextSecurePreferences.getLocalUuid(context) == null) {
|
||||
if (TextSecurePreferences.getLocalNumber(context) == null || TextSecurePreferences.getLocalAci(context) == null) {
|
||||
return "Self not yet available!";
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ final class LogSectionKeyPreferences implements LogSection {
|
||||
.append("Client Deprecated : ").append(SignalStore.misc().isClientDeprecated()).append("\n")
|
||||
.append("Push Registered : ").append(TextSecurePreferences.isPushRegistered(context)).append("\n")
|
||||
.append("Unauthorized Received: ").append(TextSecurePreferences.isUnauthorizedRecieved(context)).append("\n")
|
||||
.append("self.isRegistered() : ").append(TextSecurePreferences.getLocalUuid(context) == null ? "false" : Recipient.self().isRegistered()).append("\n")
|
||||
.append("self.isRegistered() : ").append(TextSecurePreferences.getLocalAci(context) == null ? "false" : Recipient.self().isRegistered()).append("\n")
|
||||
.append("Thread Trimming : ").append(getThreadTrimmingString()).append("\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import com.google.android.gms.common.GoogleApiAvailability;
|
||||
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.emoji.EmojiFiles;
|
||||
import org.thoughtcrime.securesms.emoji.EmojiSource;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.AppSignatureUtil;
|
||||
@@ -27,12 +26,11 @@ import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.VersionTracker;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LogSectionSystemInfo implements LogSection {
|
||||
@@ -64,7 +62,7 @@ public class LogSectionSystemInfo implements LogSection {
|
||||
builder.append("MemInfo : ").append(getMemoryInfo(context)).append("\n");
|
||||
builder.append("OS Host : ").append(Build.HOST).append("\n");
|
||||
builder.append("RecipientId : ").append(SignalStore.registrationValues().isRegistrationComplete() ? Recipient.self().getId() : "N/A").append("\n");
|
||||
builder.append("UUID : ").append(getCensoredUuid(context)).append("\n");
|
||||
builder.append("ACI : ").append(getCensoredAci(context)).append("\n");
|
||||
builder.append("Censored : ").append(CensorshipUtil.isCensored(context)).append("\n");
|
||||
builder.append("Play Services : ").append(getPlayServicesString(context)).append("\n");
|
||||
builder.append("FCM : ").append(!TextSecurePreferences.isFcmDisabled(context)).append("\n");
|
||||
@@ -166,12 +164,12 @@ public class LogSectionSystemInfo implements LogSection {
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCensoredUuid(@NonNull Context context) {
|
||||
UUID uuid = TextSecurePreferences.getLocalUuid(context);
|
||||
private static String getCensoredAci(@NonNull Context context) {
|
||||
ACI aci = TextSecurePreferences.getLocalAci(context);
|
||||
|
||||
if (uuid != null) {
|
||||
String uuidString = uuid.toString();
|
||||
String lastTwo = uuidString.substring(uuidString.length() - 2);
|
||||
if (aci != null) {
|
||||
String aciString = aci.toString();
|
||||
String lastTwo = aciString.substring(aciString.length() - 2);
|
||||
|
||||
return "********-****-****-****-**********" + lastTwo;
|
||||
} else {
|
||||
|
||||
@@ -174,9 +174,9 @@ public final class GroupSendUtil {
|
||||
boolean validMembership = groupRecord.isPresent() && groupRecord.get().getMembers().contains(recipient.getId());
|
||||
|
||||
if (recipient.getSenderKeyCapability() == Recipient.Capability.SUPPORTED &&
|
||||
recipient.hasUuid() &&
|
||||
access.isPresent() &&
|
||||
access.get().getTargetUnidentifiedAccess().isPresent() &&
|
||||
recipient.hasAci() &&
|
||||
access.isPresent() &&
|
||||
access.get().getTargetUnidentifiedAccess().isPresent() &&
|
||||
validMembership)
|
||||
{
|
||||
senderKeyTargets.add(recipient);
|
||||
@@ -312,8 +312,8 @@ public final class GroupSendUtil {
|
||||
Log.w(TAG, "There are " + unregisteredTargets.size() + " unregistered targets. Including failure results.");
|
||||
|
||||
List<SendMessageResult> unregisteredResults = unregisteredTargets.stream()
|
||||
.filter(Recipient::hasUuid)
|
||||
.map(t -> SendMessageResult.unregisteredFailure(new SignalServiceAddress(t.requireUuid(), t.getE164().orNull())))
|
||||
.filter(Recipient::hasAci)
|
||||
.map(t -> SendMessageResult.unregisteredFailure(new SignalServiceAddress(t.requireAci(), t.getE164().orNull())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (unregisteredResults.size() < unregisteredTargets.size()) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.contactshare.ContactModelMapper;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.SecurityEvent;
|
||||
import org.thoughtcrime.securesms.crypto.SessionUtil;
|
||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
@@ -83,7 +82,6 @@ import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
|
||||
import org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob;
|
||||
import org.thoughtcrime.securesms.jobs.SenderKeyDistributionSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
|
||||
import org.thoughtcrime.securesms.jobs.ThreadUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.TrimThreadJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
@@ -123,7 +121,6 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.SignalProtocolAddress;
|
||||
import org.whispersystems.libsignal.protocol.DecryptionErrorMessage;
|
||||
import org.whispersystems.libsignal.state.SessionStore;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
@@ -643,7 +640,7 @@ public final class MessageContentProcessor {
|
||||
}
|
||||
|
||||
ApplicationDependencies.getSignalCallManager()
|
||||
.receivedOpaqueMessage(new WebRtcData.OpaqueMessageMetadata(senderRecipient.requireUuid(),
|
||||
.receivedOpaqueMessage(new WebRtcData.OpaqueMessageMetadata(senderRecipient.requireAci().uuid(),
|
||||
message.getOpaque(),
|
||||
content.getSenderDevice(),
|
||||
messageAgeSeconds));
|
||||
@@ -1021,7 +1018,7 @@ public final class MessageContentProcessor {
|
||||
|
||||
private void handleSynchronizeOutgoingPayment(@NonNull SignalServiceContent content, @NonNull OutgoingPaymentMessage outgoingPaymentMessage) {
|
||||
RecipientId recipientId = outgoingPaymentMessage.getRecipient()
|
||||
.transform(uuid -> RecipientId.from(uuid, null))
|
||||
.transform(RecipientId::from)
|
||||
.orNull();
|
||||
long timestamp = outgoingPaymentMessage.getBlockTimestamp();
|
||||
if (timestamp == 0) {
|
||||
@@ -1811,7 +1808,7 @@ public final class MessageContentProcessor {
|
||||
|
||||
warn(content.getTimestamp(), "[RetryReceipt] Received a retry receipt from " + formatSender(senderRecipient, content) + " for message with timestamp " + sentTimestamp + ".");
|
||||
|
||||
if (!senderRecipient.hasUuid()) {
|
||||
if (!senderRecipient.hasAci()) {
|
||||
warn(content.getTimestamp(), "[RetryReceipt] Requester " + senderRecipient.getId() + " somehow has no UUID! timestamp: " + sentTimestamp);
|
||||
return;
|
||||
}
|
||||
@@ -1851,7 +1848,7 @@ public final class MessageContentProcessor {
|
||||
|
||||
GroupId.V2 groupId = threadRecipient.requireGroupId().requireV2();
|
||||
DistributionId distributionId = DatabaseFactory.getGroupDatabase(context).getOrCreateDistributionId(groupId);
|
||||
SignalProtocolAddress requesterAddress = new SignalProtocolAddress(requester.requireUuid().toString(), content.getSenderDevice());
|
||||
SignalProtocolAddress requesterAddress = new SignalProtocolAddress(requester.requireAci().toString(), content.getSenderDevice());
|
||||
|
||||
DatabaseFactory.getSenderKeySharedDatabase(context).delete(distributionId, Collections.singleton(requesterAddress));
|
||||
|
||||
@@ -2090,7 +2087,7 @@ public final class MessageContentProcessor {
|
||||
List<Mention> mentions = new ArrayList<>(signalServiceMentions.size());
|
||||
|
||||
for (SignalServiceDataMessage.Mention mention : signalServiceMentions) {
|
||||
mentions.add(new Mention(Recipient.externalPush(context, mention.getUuid(), null, false).getId(), mention.getStart(), mention.getLength()));
|
||||
mentions.add(new Mention(Recipient.externalPush(context, mention.getAci(), null, false).getId(), mention.getStart(), mention.getLength()));
|
||||
}
|
||||
|
||||
return mentions;
|
||||
@@ -2229,8 +2226,8 @@ public final class MessageContentProcessor {
|
||||
if (recipient.hasE164()) {
|
||||
unidentified |= message.isUnidentified(recipient.requireE164());
|
||||
}
|
||||
if (recipient.hasUuid()) {
|
||||
unidentified |= message.isUnidentified(recipient.requireUuid());
|
||||
if (recipient.hasAci()) {
|
||||
unidentified |= message.isUnidentified(recipient.requireAci());
|
||||
}
|
||||
|
||||
return unidentified;
|
||||
|
||||
@@ -78,7 +78,7 @@ public final class MessageDecryptionUtil {
|
||||
*/
|
||||
public static @NonNull DecryptionResult decrypt(@NonNull Context context, @NonNull SignalServiceEnvelope envelope) {
|
||||
SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalUuid(context), Optional.of(TextSecurePreferences.getLocalNumber(context)));
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalAci(context), Optional.of(TextSecurePreferences.getLocalNumber(context)));
|
||||
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, ReentrantSessionLock.INSTANCE, UnidentifiedAccessUtil.getCertificateValidator());
|
||||
List<Job> jobs = new LinkedList<>();
|
||||
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class AccountRecordMigrationJob extends MigrationJob {
|
||||
|
||||
@Override
|
||||
public void performMigration() {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalUuid(context) == null) {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalAci(context) == null) {
|
||||
Log.w(TAG, "Not registered!");
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-3
@@ -7,10 +7,8 @@ import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobs.StorageSyncJob;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
@@ -47,7 +45,7 @@ public class ApplyUnknownFieldsToSelfMigrationJob extends MigrationJob {
|
||||
|
||||
@Override
|
||||
public void performMigration() {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalUuid(context) == null) {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalAci(context) == null) {
|
||||
Log.w(TAG, "Not registered!");
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ public final class DirectoryRefreshMigrationJob extends MigrationJob {
|
||||
public void performMigration() throws IOException {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||
!SignalStore.registrationValues().isRegistrationComplete() ||
|
||||
TextSecurePreferences.getLocalUuid(context) == null)
|
||||
TextSecurePreferences.getLocalAci(context) == null)
|
||||
{
|
||||
Log.w(TAG, "Not registered! Skipping.");
|
||||
return;
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ public class StorageServiceMigrationJob extends MigrationJob {
|
||||
|
||||
@Override
|
||||
public void performMigration() {
|
||||
if (TextSecurePreferences.getLocalUuid(context) == null) {
|
||||
if (TextSecurePreferences.getLocalAci(context) == null) {
|
||||
Log.w(TAG, "Self not yet available.");
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ public class UserNotificationMigrationJob extends MigrationJob {
|
||||
void performMigration() {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||
TextSecurePreferences.getLocalNumber(context) == null ||
|
||||
TextSecurePreferences.getLocalUuid(context) == null)
|
||||
TextSecurePreferences.getLocalAci(context) == null)
|
||||
{
|
||||
Log.w(TAG, "Not registered! Skipping.");
|
||||
return;
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
@@ -70,10 +71,10 @@ public class UuidMigrationJob extends MigrationJob {
|
||||
|
||||
private static void fetchOwnUuid(@NonNull Context context) throws IOException {
|
||||
RecipientId self = Recipient.self().getId();
|
||||
UUID localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnUuid();
|
||||
ACI localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnAci();
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).markRegisteredOrThrow(self, localUuid);
|
||||
TextSecurePreferences.setLocalUuid(context, localUuid);
|
||||
TextSecurePreferences.setLocalAci(context, localUuid);
|
||||
}
|
||||
|
||||
public static class Factory implements Job.Factory<UuidMigrationJob> {
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||
@@ -191,7 +192,7 @@ public final class MessageGroupContext {
|
||||
List<RecipientId> members = new ArrayList<>(decryptedGroupV2Context.getGroupState().getMembersCount());
|
||||
|
||||
for (DecryptedMember member : decryptedGroupV2Context.getGroupState().getMembersList()) {
|
||||
RecipientId recipient = RecipientId.from(UuidUtil.fromByteString(member.getUuid()), null);
|
||||
RecipientId recipient = RecipientId.from(ACI.fromByteString(member.getUuid()), null);
|
||||
if (!Recipient.self().getId().equals(recipient)) {
|
||||
members.add(recipient);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -19,7 +20,7 @@ public class AccountManagerFactory {
|
||||
private static final String TAG = Log.tag(AccountManagerFactory.class);
|
||||
|
||||
public static @NonNull SignalServiceAccountManager createAuthenticated(@NonNull Context context,
|
||||
@NonNull UUID uuid,
|
||||
@NonNull ACI aci,
|
||||
@NonNull String number,
|
||||
@NonNull String password)
|
||||
{
|
||||
@@ -34,7 +35,11 @@ public class AccountManagerFactory {
|
||||
}
|
||||
|
||||
return new SignalServiceAccountManager(new SignalServiceNetworkAccess(context).getConfiguration(number),
|
||||
uuid, number, password, BuildConfig.SIGNAL_AGENT, FeatureFlags.okHttpAutomaticRetry());
|
||||
aci,
|
||||
number,
|
||||
password,
|
||||
BuildConfig.SIGNAL_AGENT,
|
||||
FeatureFlags.okHttpAutomaticRetry());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.util.LRUCache;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.concurrent.FilteredExecutor;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -160,11 +161,11 @@ public final class LiveRecipientCache {
|
||||
}
|
||||
|
||||
if (selfId == null) {
|
||||
UUID localUuid = TextSecurePreferences.getLocalUuid(context);
|
||||
ACI localAci = TextSecurePreferences.getLocalAci(context);
|
||||
String localE164 = TextSecurePreferences.getLocalNumber(context);
|
||||
|
||||
if (localUuid != null) {
|
||||
selfId = recipientDatabase.getByUuid(localUuid).or(recipientDatabase.getByE164(localE164)).orNull();
|
||||
if (localAci != null) {
|
||||
selfId = recipientDatabase.getByAci(localAci).or(recipientDatabase.getByE164(localE164)).orNull();
|
||||
} else if (localE164 != null) {
|
||||
selfId = recipientDatabase.getByE164(localE164).orNull();
|
||||
} else {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.MentionSetting;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.RecipientExtras;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
@@ -77,7 +78,7 @@ public class Recipient {
|
||||
|
||||
private final RecipientId id;
|
||||
private final boolean resolving;
|
||||
private final UUID uuid;
|
||||
private final ACI aci;
|
||||
private final String username;
|
||||
private final String e164;
|
||||
private final String email;
|
||||
@@ -163,8 +164,8 @@ public class Recipient {
|
||||
* Returns a fully-populated {@link Recipient} and associates it with the provided username.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalUsername(@NonNull Context context, @NonNull UUID uuid, @NonNull String username) {
|
||||
Recipient recipient = externalPush(context, uuid, null, false);
|
||||
public static @NonNull Recipient externalUsername(@NonNull Context context, @NonNull ACI aci, @NonNull String username) {
|
||||
Recipient recipient = externalPush(context, aci, null, false);
|
||||
DatabaseFactory.getRecipientDatabase(context).setUsername(recipient.getId(), username);
|
||||
return recipient;
|
||||
}
|
||||
@@ -172,11 +173,11 @@ public class Recipient {
|
||||
/**
|
||||
* Returns a fully-populated {@link Recipient} based off of a {@link SignalServiceAddress},
|
||||
* creating one in the database if necessary. Convenience overload of
|
||||
* {@link #externalPush(Context, UUID, String, boolean)}
|
||||
* {@link #externalPush(Context, ACI, String, boolean)}
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) {
|
||||
return externalPush(context, signalServiceAddress.getUuid(), signalServiceAddress.getNumber().orNull(), false);
|
||||
return externalPush(context, signalServiceAddress.getAci(), signalServiceAddress.getNumber().orNull(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +190,7 @@ public class Recipient {
|
||||
if (address.getNumber().isPresent()) {
|
||||
return externalPush(context, null, address.getNumber().get(), false);
|
||||
} else {
|
||||
return externalPush(context, address.getUuid(), null, false);
|
||||
return externalPush(context, address.getAci(), null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +205,7 @@ public class Recipient {
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalHighTrustPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) {
|
||||
return externalPush(context, signalServiceAddress.getUuid(), signalServiceAddress.getNumber().orNull(), true);
|
||||
return externalPush(context, signalServiceAddress.getAci(), signalServiceAddress.getNumber().orNull(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,19 +221,19 @@ public class Recipient {
|
||||
* that can be trusted as accurate (like an envelope).
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalPush(@NonNull Context context, @Nullable UUID uuid, @Nullable String e164, boolean highTrust) {
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(uuid)) {
|
||||
public static @NonNull Recipient externalPush(@NonNull Context context, @Nullable ACI aci, @Nullable String e164, boolean highTrust) {
|
||||
if (UuidUtil.UNKNOWN_UUID.equals(aci)) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
RecipientDatabase db = DatabaseFactory.getRecipientDatabase(context);
|
||||
RecipientId recipientId = db.getAndPossiblyMerge(uuid, e164, highTrust);
|
||||
RecipientId recipientId = db.getAndPossiblyMerge(aci, e164, highTrust);
|
||||
|
||||
Recipient resolved = resolved(recipientId);
|
||||
|
||||
if (highTrust && !resolved.isRegistered() && uuid != null) {
|
||||
if (highTrust && !resolved.isRegistered() && aci != null) {
|
||||
Log.w(TAG, "External high-trust push was locally marked unregistered. Marking as registered.");
|
||||
db.markRegistered(recipientId, uuid);
|
||||
db.markRegistered(recipientId, aci);
|
||||
} else if (highTrust && !resolved.isRegistered()) {
|
||||
Log.w(TAG, "External high-trust push was locally marked unregistered, but we don't have a UUID, so we can't do anything.", new Throwable());
|
||||
}
|
||||
@@ -298,7 +299,7 @@ public class Recipient {
|
||||
* or serialized groupId.
|
||||
*
|
||||
* If the identifier is a UUID of a Signal user, prefer using
|
||||
* {@link #externalPush(Context, UUID, String, boolean)} or its overload, as this will let us associate
|
||||
* {@link #externalPush(Context, ACI, String, boolean)} or its overload, as this will let us associate
|
||||
* the phone number with the recipient.
|
||||
*/
|
||||
@WorkerThread
|
||||
@@ -309,8 +310,8 @@ public class Recipient {
|
||||
RecipientId id = null;
|
||||
|
||||
if (UuidUtil.isUuid(identifier)) {
|
||||
UUID uuid = UuidUtil.parseOrThrow(identifier);
|
||||
id = db.getOrInsertFromUuid(uuid);
|
||||
ACI uuid = ACI.parseOrThrow(identifier);
|
||||
id = db.getOrInsertFromAci(uuid);
|
||||
} else if (GroupId.isEncodedGroup(identifier)) {
|
||||
id = db.getOrInsertFromGroupId(GroupId.parseOrThrow(identifier));
|
||||
} else if (NumberUtil.isValidEmail(identifier)) {
|
||||
@@ -329,9 +330,9 @@ public class Recipient {
|
||||
|
||||
Recipient(@NonNull RecipientId id) {
|
||||
this.id = id;
|
||||
this.resolving = true;
|
||||
this.uuid = null;
|
||||
this.username = null;
|
||||
this.resolving = true;
|
||||
this.aci = null;
|
||||
this.username = null;
|
||||
this.e164 = null;
|
||||
this.email = null;
|
||||
this.groupId = null;
|
||||
@@ -384,7 +385,7 @@ public class Recipient {
|
||||
public Recipient(@NonNull RecipientId id, @NonNull RecipientDetails details, boolean resolved) {
|
||||
this.id = id;
|
||||
this.resolving = !resolved;
|
||||
this.uuid = details.uuid;
|
||||
this.aci = details.aci;
|
||||
this.username = details.username;
|
||||
this.e164 = details.e164;
|
||||
this.email = details.email;
|
||||
@@ -603,8 +604,8 @@ public class Recipient {
|
||||
return StringUtil.isolateBidi(name);
|
||||
}
|
||||
|
||||
public @NonNull Optional<UUID> getUuid() {
|
||||
return Optional.fromNullable(uuid);
|
||||
public @NonNull Optional<ACI> getAci() {
|
||||
return Optional.fromNullable(aci);
|
||||
}
|
||||
|
||||
public @NonNull Optional<String> getUsername() {
|
||||
@@ -631,8 +632,8 @@ public class Recipient {
|
||||
return Optional.fromNullable(e164).or(Optional.fromNullable(email));
|
||||
}
|
||||
|
||||
public @NonNull UUID requireUuid() {
|
||||
UUID resolved = resolving ? resolve().uuid : uuid;
|
||||
public @NonNull ACI requireAci() {
|
||||
ACI resolved = resolving ? resolve().aci : aci;
|
||||
|
||||
if (resolved == null) {
|
||||
throw new MissingAddressError(id);
|
||||
@@ -682,12 +683,12 @@ public class Recipient {
|
||||
return getE164().isPresent();
|
||||
}
|
||||
|
||||
public boolean hasUuid() {
|
||||
return getUuid().isPresent();
|
||||
public boolean hasAci() {
|
||||
return getAci().isPresent();
|
||||
}
|
||||
|
||||
public boolean isUuidOnly() {
|
||||
return hasUuid() && !hasSmsAddress();
|
||||
public boolean isAciOnly() {
|
||||
return hasAci() && !hasSmsAddress();
|
||||
}
|
||||
|
||||
public @NonNull GroupId requireGroupId() {
|
||||
@@ -701,18 +702,18 @@ public class Recipient {
|
||||
}
|
||||
|
||||
public boolean hasServiceIdentifier() {
|
||||
return uuid != null || e164 != null;
|
||||
return aci != null || e164 != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string identifier able to be used with the Signal service. Prefers UUID, and if not
|
||||
* @return A string identifier able to be used with the Signal service. Prefers ACI, and if not
|
||||
* available, will return an E164 number.
|
||||
*/
|
||||
public @NonNull String requireServiceId() {
|
||||
Recipient resolved = resolving ? resolve() : this;
|
||||
|
||||
if (resolved.getUuid().isPresent()) {
|
||||
return resolved.getUuid().get().toString();
|
||||
if (resolved.getAci().isPresent()) {
|
||||
return resolved.requireAci().toString();
|
||||
} else {
|
||||
return getE164().get();
|
||||
}
|
||||
@@ -721,15 +722,15 @@ public class Recipient {
|
||||
/**
|
||||
* @return A single string to represent the recipient, in order of precedence:
|
||||
*
|
||||
* Group ID > UUID > Phone > Email
|
||||
* Group ID > ACI > Phone > Email
|
||||
*/
|
||||
public @NonNull String requireStringId() {
|
||||
Recipient resolved = resolving ? resolve() : this;
|
||||
|
||||
if (resolved.isGroup()) {
|
||||
return resolved.requireGroupId().toString();
|
||||
} else if (resolved.getUuid().isPresent()) {
|
||||
return resolved.getUuid().get().toString();
|
||||
} else if (resolved.getAci().isPresent()) {
|
||||
return resolved.requireAci().toString();
|
||||
}
|
||||
|
||||
return requireSmsAddress();
|
||||
@@ -1183,7 +1184,7 @@ public class Recipient {
|
||||
lastProfileFetch == other.lastProfileFetch &&
|
||||
forceSmsSelection == other.forceSmsSelection &&
|
||||
Objects.equals(id, other.id) &&
|
||||
Objects.equals(uuid, other.uuid) &&
|
||||
Objects.equals(aci, other.aci) &&
|
||||
Objects.equals(username, other.username) &&
|
||||
Objects.equals(e164, other.e164) &&
|
||||
Objects.equals(email, other.email) &&
|
||||
|
||||
@@ -22,15 +22,15 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class RecipientDetails {
|
||||
|
||||
final UUID uuid;
|
||||
final ACI aci;
|
||||
final String username;
|
||||
final String e164;
|
||||
final String email;
|
||||
@@ -94,7 +94,7 @@ public class RecipientDetails {
|
||||
this.systemContactPhoto = Util.uri(settings.getSystemContactPhotoUri());
|
||||
this.customLabel = settings.getSystemPhoneLabel();
|
||||
this.contactUri = Util.uri(settings.getSystemContactUri());
|
||||
this.uuid = settings.getUuid();
|
||||
this.aci = settings.getAci();
|
||||
this.username = settings.getUsername();
|
||||
this.e164 = settings.getE164();
|
||||
this.email = settings.getEmail();
|
||||
@@ -149,9 +149,9 @@ public class RecipientDetails {
|
||||
this.groupAvatarId = null;
|
||||
this.systemContactPhoto = null;
|
||||
this.customLabel = null;
|
||||
this.contactUri = null;
|
||||
this.uuid = null;
|
||||
this.username = null;
|
||||
this.contactUri = null;
|
||||
this.aci = null;
|
||||
this.username = null;
|
||||
this.e164 = null;
|
||||
this.email = null;
|
||||
this.groupId = null;
|
||||
@@ -201,7 +201,7 @@ public class RecipientDetails {
|
||||
public static @NonNull RecipientDetails forIndividual(@NonNull Context context, @NonNull RecipientSettings settings) {
|
||||
boolean systemContact = !settings.getSystemProfileName().isEmpty();
|
||||
boolean isSelf = (settings.getE164() != null && settings.getE164().equals(TextSecurePreferences.getLocalNumber(context))) ||
|
||||
(settings.getUuid() != null && settings.getUuid().equals(TextSecurePreferences.getLocalUuid(context)));
|
||||
(settings.getAci() != null && settings.getAci().equals(TextSecurePreferences.getLocalAci(context)));
|
||||
|
||||
RegisteredState registeredState = settings.getRegistered();
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.annimon.stream.Stream;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
@@ -54,7 +55,7 @@ public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
||||
|
||||
@AnyThread
|
||||
public static @NonNull RecipientId from(@NonNull SignalServiceAddress address) {
|
||||
return from(address.getUuid(), address.getNumber().orNull(), false);
|
||||
return from(address.getAci(), address.getNumber().orNull(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +66,7 @@ public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
||||
@AnyThread
|
||||
public static @NonNull RecipientId fromExternalPush(@NonNull String identifier) {
|
||||
if (UuidUtil.isUuid(identifier)) {
|
||||
return from(UuidUtil.parseOrThrow(identifier), null);
|
||||
return from(ACI.parseOrThrow(identifier), null);
|
||||
} else {
|
||||
return from(null, identifier);
|
||||
}
|
||||
@@ -77,7 +78,7 @@ public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
||||
*/
|
||||
@AnyThread
|
||||
public static @NonNull RecipientId fromHighTrust(@NonNull SignalServiceAddress address) {
|
||||
return from(address.getUuid(), address.getNumber().orNull(), true);
|
||||
return from(address.getAci(), address.getNumber().orNull(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,17 +86,17 @@ public class RecipientId implements Parcelable, Comparable<RecipientId> {
|
||||
*/
|
||||
@AnyThread
|
||||
@SuppressLint("WrongThread")
|
||||
public static @NonNull RecipientId from(@Nullable UUID uuid, @Nullable String e164) {
|
||||
return from(uuid, e164, false);
|
||||
public static @NonNull RecipientId from(@Nullable ACI aci, @Nullable String e164) {
|
||||
return from(aci, e164, false);
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@SuppressLint("WrongThread")
|
||||
private static @NonNull RecipientId from(@Nullable UUID uuid, @Nullable String e164, boolean highTrust) {
|
||||
RecipientId recipientId = RecipientIdCache.INSTANCE.get(uuid, e164);
|
||||
private static @NonNull RecipientId from(@Nullable ACI aci, @Nullable String e164, boolean highTrust) {
|
||||
RecipientId recipientId = RecipientIdCache.INSTANCE.get(aci, e164);
|
||||
|
||||
if (recipientId == null) {
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), uuid, e164, highTrust);
|
||||
Recipient recipient = Recipient.externalPush(ApplicationDependencies.getApplication(), aci, e164, highTrust);
|
||||
RecipientIdCache.INSTANCE.put(recipient);
|
||||
recipientId = recipient.getId();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@@ -35,35 +36,35 @@ final class RecipientIdCache {
|
||||
synchronized void put(@NonNull Recipient recipient) {
|
||||
RecipientId recipientId = recipient.getId();
|
||||
Optional<String> e164 = recipient.getE164();
|
||||
Optional<UUID> uuid = recipient.getUuid();
|
||||
Optional<ACI> aci = recipient.getAci();
|
||||
|
||||
if (e164.isPresent()) {
|
||||
ids.put(e164.get(), recipientId);
|
||||
}
|
||||
|
||||
if (uuid.isPresent()) {
|
||||
ids.put(uuid.get(), recipientId);
|
||||
if (aci.isPresent()) {
|
||||
ids.put(aci.get(), recipientId);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized @Nullable RecipientId get(@Nullable UUID uuid, @Nullable String e164) {
|
||||
if (uuid != null && e164 != null) {
|
||||
RecipientId recipientIdByUuid = ids.get(uuid);
|
||||
if (recipientIdByUuid == null) return null;
|
||||
synchronized @Nullable RecipientId get(@Nullable ACI aci, @Nullable String e164) {
|
||||
if (aci != null && e164 != null) {
|
||||
RecipientId recipientIdByAci = ids.get(aci);
|
||||
if (recipientIdByAci == null) return null;
|
||||
|
||||
RecipientId recipientIdByE164 = ids.get(e164);
|
||||
if (recipientIdByE164 == null) return null;
|
||||
|
||||
if (recipientIdByUuid.equals(recipientIdByE164)) {
|
||||
return recipientIdByUuid;
|
||||
if (recipientIdByAci.equals(recipientIdByE164)) {
|
||||
return recipientIdByAci;
|
||||
} else {
|
||||
ids.remove(uuid);
|
||||
ids.remove(aci);
|
||||
ids.remove(e164);
|
||||
Log.w(TAG, "Seen invalid RecipientIdCacheState");
|
||||
return null;
|
||||
}
|
||||
} else if (uuid != null) {
|
||||
return ids.get(uuid);
|
||||
} else if (aci != null) {
|
||||
return ids.get(aci);
|
||||
} else if (e164 != null) {
|
||||
return ids.get(e164);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RecipientUtil {
|
||||
|
||||
@@ -50,11 +49,11 @@ public class RecipientUtil {
|
||||
{
|
||||
recipient = recipient.resolve();
|
||||
|
||||
if (!recipient.getUuid().isPresent() && !recipient.getE164().isPresent()) {
|
||||
if (!recipient.getAci().isPresent() && !recipient.getE164().isPresent()) {
|
||||
throw new AssertionError(recipient.getId() + " - No UUID or phone number!");
|
||||
}
|
||||
|
||||
if (!recipient.getUuid().isPresent()) {
|
||||
if (!recipient.getAci().isPresent()) {
|
||||
Log.i(TAG, recipient.getId() + " is missing a UUID...");
|
||||
RegisteredState state = DirectoryHelper.refreshDirectoryFor(context, recipient, false);
|
||||
|
||||
@@ -62,8 +61,8 @@ public class RecipientUtil {
|
||||
Log.i(TAG, "Successfully performed a UUID fetch for " + recipient.getId() + ". Registered: " + state);
|
||||
}
|
||||
|
||||
if (recipient.hasUuid()) {
|
||||
return new SignalServiceAddress(recipient.requireUuid(), Optional.fromNullable(recipient.resolve().getE164().orNull()));
|
||||
if (recipient.hasAci()) {
|
||||
return new SignalServiceAddress(recipient.requireAci(), Optional.fromNullable(recipient.resolve().getE164().orNull()));
|
||||
} else {
|
||||
throw new NotFoundException(recipient.getId() + " is not registered!");
|
||||
}
|
||||
@@ -82,7 +81,7 @@ public class RecipientUtil {
|
||||
|
||||
return Stream.of(recipients)
|
||||
.map(Recipient::resolve)
|
||||
.map(r -> new SignalServiceAddress(r.requireUuid(), r.getE164().orNull()))
|
||||
.map(r -> new SignalServiceAddress(r.requireAci(), r.getE164().orNull()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -94,7 +93,7 @@ public class RecipientUtil {
|
||||
{
|
||||
List<Recipient> recipientsWithoutUuids = Stream.of(recipients)
|
||||
.map(Recipient::resolve)
|
||||
.filterNot(Recipient::hasUuid)
|
||||
.filterNot(Recipient::hasAci)
|
||||
.toList();
|
||||
|
||||
if (recipientsWithoutUuids.size() > 0) {
|
||||
|
||||
+6
-6
@@ -36,13 +36,13 @@ import org.whispersystems.libsignal.util.KeyHelper;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.KbsPinData;
|
||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
@@ -128,14 +128,14 @@ public final class RegistrationRepository {
|
||||
SessionUtil.archiveAllSessions();
|
||||
SenderKeyUtil.clearAllState(context);
|
||||
|
||||
UUID uuid = UuidUtil.parseOrThrow(response.getUuid());
|
||||
ACI aci = ACI.parseOrThrow(response.getUuid());
|
||||
boolean hasPin = response.isStorageCapable();
|
||||
|
||||
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context);
|
||||
List<PreKeyRecord> records = PreKeyUtil.generatePreKeys(context);
|
||||
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateSignedPreKey(context, identityKey, true);
|
||||
|
||||
SignalServiceAccountManager accountManager = AccountManagerFactory.createAuthenticated(context, uuid, registrationData.getE164(), registrationData.getPassword());
|
||||
SignalServiceAccountManager accountManager = AccountManagerFactory.createAuthenticated(context, aci, registrationData.getE164(), registrationData.getPassword());
|
||||
accountManager.setPreKeys(identityKey.getPublicKey(), signedPreKey, records);
|
||||
|
||||
if (registrationData.isFcm()) {
|
||||
@@ -143,13 +143,13 @@ public final class RegistrationRepository {
|
||||
}
|
||||
|
||||
RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
|
||||
RecipientId selfId = Recipient.externalPush(context, uuid, registrationData.getE164(), true).getId();
|
||||
RecipientId selfId = Recipient.externalPush(context, aci, registrationData.getE164(), true).getId();
|
||||
|
||||
recipientDatabase.setProfileSharing(selfId, true);
|
||||
recipientDatabase.markRegisteredOrThrow(selfId, uuid);
|
||||
recipientDatabase.markRegisteredOrThrow(selfId, aci);
|
||||
|
||||
TextSecurePreferences.setLocalNumber(context, registrationData.getE164());
|
||||
TextSecurePreferences.setLocalUuid(context, uuid);
|
||||
TextSecurePreferences.setLocalAci(context, aci);
|
||||
recipientDatabase.setProfileKey(selfId, registrationData.getProfileKey());
|
||||
ApplicationDependencies.getRecipientCache().clearSelf();
|
||||
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
||||
import org.webrtc.VideoTrack;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -82,7 +83,7 @@ public class GroupActionProcessor extends DeviceAwareActionProcessor {
|
||||
seen.add(Recipient.self());
|
||||
|
||||
for (GroupCall.RemoteDeviceState device : remoteDeviceStates) {
|
||||
Recipient recipient = Recipient.externalPush(context, device.getUserId(), null, false);
|
||||
Recipient recipient = Recipient.externalPush(context, ACI.from(device.getUserId()), null, false);
|
||||
CallParticipantId callParticipantId = new CallParticipantId(device.getDemuxId(), recipient.getId());
|
||||
CallParticipant callParticipant = participants.get(callParticipantId);
|
||||
|
||||
|
||||
+3
-3
@@ -122,8 +122,8 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
|
||||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId);
|
||||
|
||||
List<UUID> members = new ArrayList<>(peekInfo.getJoinedMembers());
|
||||
if (!members.contains(Recipient.self().requireUuid())) {
|
||||
members.add(Recipient.self().requireUuid());
|
||||
if (!members.contains(Recipient.self().requireAci().uuid())) {
|
||||
members.add(Recipient.self().requireAci().uuid());
|
||||
}
|
||||
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, WebRtcUtil.isCallFull(peekInfo));
|
||||
|
||||
@@ -148,7 +148,7 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
|
||||
String eraId = WebRtcUtil.getGroupCallEraId(groupCall);
|
||||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId);
|
||||
|
||||
List<UUID> members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireUuid()).toList();
|
||||
List<UUID> members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireAci().uuid()).toList();
|
||||
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, false);
|
||||
|
||||
currentState = currentState.builder()
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceStateBuilder;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -108,7 +109,7 @@ public class GroupPreJoinActionProcessor extends GroupActionProcessor {
|
||||
}
|
||||
|
||||
List<Recipient> callParticipants = Stream.of(peekInfo.getJoinedMembers())
|
||||
.map(uuid -> Recipient.externalPush(context, uuid, null, false))
|
||||
.map(uuid -> Recipient.externalPush(context, ACI.from(uuid), null, false))
|
||||
.toList();
|
||||
|
||||
WebRtcServiceStateBuilder.CallInfoStateBuilder builder = currentState.builder()
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.service.webrtc.state.WebRtcServiceState;
|
||||
import org.thoughtcrime.securesms.util.NetworkUtil;
|
||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -136,7 +137,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
.changeCallSetupState()
|
||||
.isRemoteVideoOffer(true)
|
||||
.ringId(ringId)
|
||||
.ringerRecipient(Recipient.externalPush(context, uuid, null, false))
|
||||
.ringerRecipient(Recipient.externalPush(context, ACI.from(uuid), null, false))
|
||||
.commit()
|
||||
.changeCallInfoState()
|
||||
.callRecipient(remotePeerGroup.getRecipient())
|
||||
|
||||
@@ -64,6 +64,7 @@ import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OpaqueMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.TurnServerInfo;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -149,7 +150,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
serviceExecutor.execute(() -> {
|
||||
if (needsToSetSelfUuid) {
|
||||
try {
|
||||
callManager.setSelfUuid(Recipient.self().requireUuid());
|
||||
callManager.setSelfUuid(Recipient.self().requireAci().uuid());
|
||||
needsToSetSelfUuid = false;
|
||||
} catch (CallException e) {
|
||||
Log.w(TAG, "Unable to set self UUID on CallManager", e);
|
||||
@@ -593,7 +594,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall.
|
||||
SignalServiceCallMessage callMessage = SignalServiceCallMessage.forOpaque(opaqueMessage, true, null);
|
||||
|
||||
networkExecutor.execute(() -> {
|
||||
Recipient recipient = Recipient.resolved(RecipientId.from(uuid, null));
|
||||
Recipient recipient = Recipient.resolved(RecipientId.from(ACI.from(uuid), null));
|
||||
if (recipient.isBlocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
@@ -50,10 +51,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
if (address == null) {
|
||||
Log.w(TAG, "No address on the ContentRecord -- marking as invalid.");
|
||||
return true;
|
||||
} else if (address.getUuid().equals(UuidUtil.UNKNOWN_UUID)) {
|
||||
} else if (address.getAci().equals(UuidUtil.UNKNOWN_UUID)) {
|
||||
Log.w(TAG, "Found a ContactRecord without a UUID -- marking as invalid.");
|
||||
return true;
|
||||
} else if ((self.getUuid().isPresent() && address.getUuid().equals(self.requireUuid())) ||
|
||||
} else if ((self.getAci().isPresent() && address.getAci().equals(self.requireAci())) ||
|
||||
(self.getE164().isPresent() && address.getNumber().equals(self.getE164())))
|
||||
{
|
||||
Log.w(TAG, "Found a ContactRecord for ourselves -- marking as invalid.");
|
||||
@@ -66,7 +67,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
@Override
|
||||
@NonNull Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord remote, @NonNull StorageKeyGenerator keyGenerator) {
|
||||
SignalServiceAddress address = remote.getAddress();
|
||||
Optional<RecipientId> byUuid = recipientDatabase.getByUuid(address.getUuid());
|
||||
Optional<RecipientId> byUuid = recipientDatabase.getByAci(address.getAci());
|
||||
Optional<RecipientId> byE164 = address.getNumber().isPresent() ? recipientDatabase.getByE164(address.getNumber().get()) : Optional.absent();
|
||||
|
||||
return byUuid.or(byE164).transform(recipientDatabase::getRecipientSettingsForSync)
|
||||
@@ -97,9 +98,9 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
}
|
||||
|
||||
byte[] unknownFields = remote.serializeUnknownFields();
|
||||
UUID uuid = local.getAddress().getUuid() == UuidUtil.UNKNOWN_UUID ? remote.getAddress().getUuid() : local.getAddress().getUuid();
|
||||
ACI aci = local.getAddress().getAci() == ACI.UNKNOWN ? remote.getAddress().getAci() : local.getAddress().getAci();
|
||||
String e164 = remote.getAddress().getNumber().or(local.getAddress().getNumber()).orNull();
|
||||
SignalServiceAddress address = new SignalServiceAddress(uuid, e164);
|
||||
SignalServiceAddress address = new SignalServiceAddress(aci, e164);
|
||||
byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull();
|
||||
String username = remote.getUsername().or(local.getUsername()).or("");
|
||||
IdentityState identityState = remote.getIdentityState();
|
||||
@@ -146,7 +147,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
||||
|
||||
@Override
|
||||
public int compare(@NonNull SignalContactRecord lhs, @NonNull SignalContactRecord rhs) {
|
||||
if (Objects.equals(lhs.getAddress().getUuid(), rhs.getAddress().getUuid()) ||
|
||||
if (Objects.equals(lhs.getAddress().getAci(), rhs.getAddress().getAci()) ||
|
||||
Objects.equals(lhs.getAddress().getNumber(), rhs.getAddress().getNumber()))
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
||||
@@ -81,7 +82,7 @@ public final class StorageSyncModels {
|
||||
|
||||
private static @NonNull SignalAccountRecord.PinnedConversation localToRemotePinnedConversation(@NonNull RecipientSettings settings) {
|
||||
switch (settings.getGroupType()) {
|
||||
case NONE : return SignalAccountRecord.PinnedConversation.forContact(new SignalServiceAddress(settings.getUuid(), settings.getE164()));
|
||||
case NONE : return SignalAccountRecord.PinnedConversation.forContact(new SignalServiceAddress(settings.getAci(), settings.getE164()));
|
||||
case SIGNAL_V1: return SignalAccountRecord.PinnedConversation.forGroupV1(settings.getGroupId().requireV1().getDecodedId());
|
||||
case SIGNAL_V2: return SignalAccountRecord.PinnedConversation.forGroupV2(settings.getSyncExtras().getGroupMasterKey().serialize());
|
||||
default : throw new AssertionError("Unexpected group type!");
|
||||
@@ -89,13 +90,13 @@ public final class StorageSyncModels {
|
||||
}
|
||||
|
||||
private static @NonNull SignalContactRecord localToRemoteContact(@NonNull RecipientSettings recipient, byte[] rawStorageId) {
|
||||
if (recipient.getUuid() == null && recipient.getE164() == null) {
|
||||
if (recipient.getAci() == null && recipient.getE164() == null) {
|
||||
throw new AssertionError("Must have either a UUID or a phone number!");
|
||||
}
|
||||
|
||||
UUID uuid = recipient.getUuid() != null ? recipient.getUuid() : UuidUtil.UNKNOWN_UUID;
|
||||
ACI aci = recipient.getAci() != null ? recipient.getAci() : ACI.UNKNOWN;
|
||||
|
||||
return new SignalContactRecord.Builder(rawStorageId, new SignalServiceAddress(uuid, recipient.getE164()))
|
||||
return new SignalContactRecord.Builder(rawStorageId, new SignalServiceAddress(aci, recipient.getE164()))
|
||||
.setUnknownFields(recipient.getSyncExtras().getStorageProto())
|
||||
.setProfileKey(recipient.getProfileKey())
|
||||
.setGivenName(recipient.getProfileName().getGivenName())
|
||||
|
||||
@@ -7,12 +7,9 @@ import com.annimon.stream.Stream;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.SignalRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
|
||||
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
|
||||
import org.whispersystems.signalservice.api.storage.StorageId;
|
||||
@@ -145,7 +142,7 @@ public final class StorageSyncValidations {
|
||||
|
||||
if (insert.getContact().isPresent()) {
|
||||
SignalServiceAddress address = insert.getContact().get().getAddress();
|
||||
if (self.getE164().get().equals(address.getNumber().or("")) || self.getUuid().get().equals(address.getUuid())) {
|
||||
if (self.getE164().get().equals(address.getNumber().or("")) || self.requireAci().equals(address.getAci())) {
|
||||
throw new SelfAddedAsContactError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public final class BucketingUtil {
|
||||
* Calculate a user bucket for a given feature flag, uuid, and part per modulus.
|
||||
*
|
||||
* @param key Feature flag key (e.g., "research.megaphone.1")
|
||||
* @param uuid Current user's UUID (see {@link Recipient#getUuid()})
|
||||
* @param uuid Current user's UUID (see {@link Recipient#getAci()})
|
||||
* @param modulus Drives the bucketing parts per N (e.g., passing 1,000,000 indicates bucketing into parts per million)
|
||||
*/
|
||||
public static long bucket(@NonNull String key, @NonNull UUID uuid, long modulus) {
|
||||
|
||||
@@ -242,7 +242,7 @@ public class CommunicationActions {
|
||||
SimpleTask.run(() -> {
|
||||
Recipient recipient = Recipient.external(activity, e164);
|
||||
|
||||
if (!recipient.isRegistered() || !recipient.hasUuid()) {
|
||||
if (!recipient.isRegistered() || !recipient.hasAci()) {
|
||||
try {
|
||||
DirectoryHelper.refreshDirectoryFor(activity, recipient, false);
|
||||
recipient = Recipient.resolved(recipient.getId());
|
||||
|
||||
@@ -72,12 +72,12 @@ public final class LocaleFeatureFlags {
|
||||
Map<String, Integer> countryCodeValues = parseCountryValues(serialized, 0);
|
||||
Recipient self = Recipient.self();
|
||||
|
||||
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getUuid().isPresent()) {
|
||||
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getAci().isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long countEnabled = getCountryValue(countryCodeValues, self.getE164().or(""), 0);
|
||||
long currentUserBucket = BucketingUtil.bucket(flag, self.requireUuid(), 1_000_000);
|
||||
long currentUserBucket = BucketingUtil.bucket(flag, self.requireAci().uuid(), 1_000_000);
|
||||
|
||||
return countEnabled > currentUserBucket;
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ public final class ProfileUtil {
|
||||
|
||||
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
|
||||
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
|
||||
String avatarPath = accountManager.setVersionedProfile(Recipient.self().getUuid().get(),
|
||||
String avatarPath = accountManager.setVersionedProfile(Recipient.self().requireAci(),
|
||||
profileKey,
|
||||
profileName.serialize(),
|
||||
about,
|
||||
@@ -321,8 +321,8 @@ public final class ProfileUtil {
|
||||
|
||||
private static @NonNull SignalServiceAddress toSignalServiceAddress(@NonNull Context context, @NonNull Recipient recipient) throws IOException {
|
||||
if (recipient.getRegistered() == RecipientDatabase.RegisteredState.NOT_REGISTERED) {
|
||||
if (recipient.hasUuid()) {
|
||||
return new SignalServiceAddress(recipient.requireUuid(), recipient.getE164().orNull());
|
||||
if (recipient.hasAci()) {
|
||||
return new SignalServiceAddress(recipient.requireAci(), recipient.getE164().orNull());
|
||||
} else {
|
||||
throw new IOException(recipient.getId() + " not registered!");
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package org.thoughtcrime.securesms.util
|
||||
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.whispersystems.signalservice.api.push.ACI
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* A list of Recipients, but with some helpful methods for retrieving them by various properties. Uses lazy properties to ensure that it will be as performant
|
||||
@@ -12,10 +12,10 @@ import java.util.UUID
|
||||
*/
|
||||
class RecipientAccessList(private val recipients: List<Recipient>) : List<Recipient> by recipients {
|
||||
|
||||
private val byUuid: Map<UUID, Recipient> by lazy {
|
||||
private val byAci: Map<ACI, Recipient> by lazy {
|
||||
recipients
|
||||
.filter { it.hasUuid() }
|
||||
.associateBy { it.requireUuid() }
|
||||
.filter { it.hasAci() }
|
||||
.associateBy { it.requireAci() }
|
||||
}
|
||||
|
||||
private val byE164: Map<String, Recipient> by lazy {
|
||||
@@ -25,10 +25,10 @@ class RecipientAccessList(private val recipients: List<Recipient>) : List<Recipi
|
||||
}
|
||||
|
||||
fun requireByAddress(address: SignalServiceAddress): Recipient {
|
||||
if (byUuid.containsKey(address.uuid)) {
|
||||
return byUuid.get(address.uuid)!!
|
||||
if (byAci.containsKey(address.aci)) {
|
||||
return byAci[address.aci]!!
|
||||
} else if (address.number.isPresent && byE164.containsKey(address.number.get())) {
|
||||
return byE164.get(address.number.get())!!
|
||||
return byE164[address.number.get()]!!
|
||||
} else {
|
||||
throw IllegalArgumentException("Could not find a matching recipient!")
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.whispersystems.libsignal.util.Medium;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
@@ -82,7 +82,7 @@ public class TextSecurePreferences {
|
||||
public static final String MMS_USER_AGENT = "pref_mms_user_agent";
|
||||
private static final String MMS_CUSTOM_USER_AGENT = "pref_custom_mms_user_agent";
|
||||
private static final String LOCAL_NUMBER_PREF = "pref_local_number";
|
||||
private static final String LOCAL_UUID_PREF = "pref_local_uuid";
|
||||
private static final String LOCAL_ACI_PREF = "pref_local_uuid";
|
||||
private static final String LOCAL_USERNAME_PREF = "pref_local_username";
|
||||
public static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
|
||||
private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
|
||||
@@ -742,12 +742,12 @@ public class TextSecurePreferences {
|
||||
setStringPreference(context, LOCAL_NUMBER_PREF, localNumber);
|
||||
}
|
||||
|
||||
public static UUID getLocalUuid(Context context) {
|
||||
return UuidUtil.parseOrNull(getStringPreference(context, LOCAL_UUID_PREF, null));
|
||||
public static ACI getLocalAci(Context context) {
|
||||
return ACI.parseOrNull(getStringPreference(context, LOCAL_ACI_PREF, null));
|
||||
}
|
||||
|
||||
public static void setLocalUuid(Context context, UUID uuid) {
|
||||
setStringPreference(context, LOCAL_UUID_PREF, uuid.toString());
|
||||
public static void setLocalAci(Context context, ACI aci) {
|
||||
setStringPreference(context, LOCAL_ACI_PREF, aci.toString());
|
||||
}
|
||||
|
||||
public static String getPushServerPassword(Context context) {
|
||||
|
||||
@@ -14,10 +14,10 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class UsernameUtil {
|
||||
@@ -51,15 +51,15 @@ public class UsernameUtil {
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static @NonNull Optional<UUID> fetchUuidForUsername(@NonNull Context context, @NonNull String username) {
|
||||
public static @NonNull Optional<ACI> fetchAciForUsername(@NonNull Context context, @NonNull String username) {
|
||||
Optional<RecipientId> localId = DatabaseFactory.getRecipientDatabase(context).getByUsername(username);
|
||||
|
||||
if (localId.isPresent()) {
|
||||
Recipient recipient = Recipient.resolved(localId.get());
|
||||
|
||||
if (recipient.getUuid().isPresent()) {
|
||||
if (recipient.getAci().isPresent()) {
|
||||
Log.i(TAG, "Found username locally -- using associated UUID.");
|
||||
return recipient.getUuid();
|
||||
return recipient.getAci();
|
||||
} else {
|
||||
Log.w(TAG, "Found username locally, but it had no associated UUID! Clearing it.");
|
||||
DatabaseFactory.getRecipientDatabase(context).clearUsernameIfExists(username);
|
||||
@@ -69,7 +69,7 @@ public class UsernameUtil {
|
||||
try {
|
||||
Log.d(TAG, "No local user with this username. Searching remotely.");
|
||||
SignalServiceProfile profile = ApplicationDependencies.getSignalServiceMessageReceiver().retrieveProfileByUsername(username, Optional.absent(), Locale.getDefault());
|
||||
return Optional.fromNullable(profile.getUuid());
|
||||
return Optional.fromNullable(profile.getAci());
|
||||
} catch (IOException e) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user