Default discoverability to 'off' until registration is complete.

This commit is contained in:
Greyson Parrelli 2024-02-06 15:52:03 -05:00 committed by Cody Henthorne
parent 879fca0e11
commit 6097e6c305
12 changed files with 52 additions and 36 deletions

View file

@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.database.SignalDatabase.Companion.recipients
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
@ -56,7 +57,7 @@ object AccountDataProcessor {
readReceipts = TextSecurePreferences.isReadReceiptsEnabled(context),
sealedSenderIndicators = TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context),
linkPreviews = SignalStore.settings().isLinkPreviewsEnabled,
notDiscoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode.isUndiscoverable,
notDiscoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode == PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE,
phoneNumberSharingMode = SignalStore.phoneNumberPrivacy().phoneNumberSharingMode.toBackupPhoneNumberSharingMode(),
preferContactAvatars = SignalStore.settings().isPreferSystemContactPhotos,
universalExpireTimer = SignalStore.settings().universalExpireTimer,
@ -86,7 +87,7 @@ object AccountDataProcessor {
TextSecurePreferences.setTypingIndicatorsEnabled(context, settings.typingIndicators)
TextSecurePreferences.setShowUnidentifiedDeliveryIndicatorsEnabled(context, settings.sealedSenderIndicators)
SignalStore.settings().isLinkPreviewsEnabled = settings.linkPreviews
SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode = if (settings.notDiscoverableByPhoneNumber) PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE else PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.DISCOVERABLE
SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode = if (settings.notDiscoverableByPhoneNumber) PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE else PhoneNumberDiscoverabilityMode.DISCOVERABLE
SignalStore.phoneNumberPrivacy().phoneNumberSharingMode = settings.phoneNumberSharingMode.toLocalPhoneNumberMode()
SignalStore.settings().isPreferSystemContactPhotos = settings.preferContactAvatars
SignalStore.settings().universalExpireTimer = settings.universalExpireTimer

View file

@ -19,7 +19,7 @@ class PhoneNumberPrivacySettingsViewModel : ViewModel() {
private val _state = mutableStateOf(
PhoneNumberPrivacySettingsState(
phoneNumberSharing = SignalStore.phoneNumberPrivacy().isPhoneNumberSharingEnabled,
discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().isDiscoverableByPhoneNumber
discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode != PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE
)
)
@ -60,7 +60,7 @@ class PhoneNumberPrivacySettingsViewModel : ViewModel() {
fun refresh() {
_state.value = PhoneNumberPrivacySettingsState(
phoneNumberSharing = SignalStore.phoneNumberPrivacy().isPhoneNumberSharingEnabled,
discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().isDiscoverableByPhoneNumber
discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode != PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE
)
}
}

View file

@ -12,6 +12,8 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode;
import org.thoughtcrime.securesms.keyvalue.SvrValues;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.registration.RegistrationRepository;
@ -97,7 +99,7 @@ public class RefreshAttributesJob extends BaseJob {
registrationLockV2 = svrValues.getRegistrationLockToken();
}
boolean phoneNumberDiscoverable = SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode().isDiscoverable();
boolean phoneNumberDiscoverable = SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode() == PhoneNumberDiscoverabilityMode.DISCOVERABLE;
String deviceName = SignalStore.account().getDeviceName();
byte[] encryptedDeviceName = (deviceName == null) ? null : DeviceNameCipher.encryptDeviceName(deviceName.getBytes(StandardCharsets.UTF_8), SignalStore.account().getAciIdentityKey());

View file

@ -23,10 +23,9 @@ public final class PhoneNumberPrivacyValues extends SignalStoreValues {
@Override
void onFirstEverAppLaunch() {
// TODO [ALAN] PhoneNumberPrivacy: During registration, set the attribute to so that new registrations start out as not listed
//getStore().beginWrite()
// .putInteger(LISTING_MODE, PhoneNumberListingMode.UNLISTED.serialize())
// .apply();
getStore().beginWrite()
.putInteger(DISCOVERABILITY_MODE, PhoneNumberDiscoverabilityMode.UNDECIDED.serialize())
.apply();
}
@Override
@ -53,11 +52,8 @@ public final class PhoneNumberPrivacyValues extends SignalStoreValues {
putInteger(SHARING_MODE, phoneNumberSharingMode.serialize());
}
public boolean isDiscoverableByPhoneNumber() {
return getPhoneNumberDiscoverabilityMode() == PhoneNumberDiscoverabilityMode.DISCOVERABLE;
}
public @NonNull PhoneNumberDiscoverabilityMode getPhoneNumberDiscoverabilityMode() {
// The default for existing users is to be discoverable, but new users are set to UNDECIDED in onFirstEverAppLaunch
return PhoneNumberDiscoverabilityMode.deserialize(getInteger(DISCOVERABILITY_MODE, PhoneNumberDiscoverabilityMode.DISCOVERABLE.serialize()));
}
@ -120,7 +116,9 @@ public final class PhoneNumberPrivacyValues extends SignalStoreValues {
public enum PhoneNumberDiscoverabilityMode {
DISCOVERABLE(0),
NOT_DISCOVERABLE(1);
NOT_DISCOVERABLE(1),
/** The user is going through registration and has not yet chosen a discoverability setting */
UNDECIDED(2);
private final int code;
@ -128,14 +126,6 @@ public final class PhoneNumberPrivacyValues extends SignalStoreValues {
this.code = code;
}
public boolean isDiscoverable() {
return this == DISCOVERABLE;
}
public boolean isUndiscoverable() {
return this == NOT_DISCOVERABLE;
}
public int serialize() {
return code;
}

View file

@ -36,7 +36,7 @@ final class LogSectionKeyPreferences implements LogSection {
.append("Roaming Download : ").append(Util.join(TextSecurePreferences.getRoamingMediaDownloadAllowed(context), ",")).append("\n")
.append("Mobile Download : ").append(Util.join(TextSecurePreferences.getMobileMediaDownloadAllowed(context), ",")).append("\n")
.append("Phone Number Sharing : ").append(SignalStore.phoneNumberPrivacy().isPhoneNumberSharingEnabled()).append(" (").append(SignalStore.phoneNumberPrivacy().getPhoneNumberSharingMode()).append(")\n")
.append("Phone Number Discoverable: ").append(SignalStore.phoneNumberPrivacy().isDiscoverableByPhoneNumber()).append(" (").append(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode()).append(")\n");
.append("Phone Number Discoverable: ").append(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode()).append("\n");
}
private static String getThreadTrimmingString() {

View file

@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.database.model.RemoteMegaphoneRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.lock.SignalPinReminderDialog;
import org.thoughtcrime.securesms.lock.SignalPinReminders;
@ -392,13 +393,13 @@ public final class Megaphones {
* Prompt megaphone 3 days after turning off phone number discovery when no username is set.
*/
private static boolean shouldShowSetUpYourUsernameMegaphone(@NonNull Map<Event, MegaphoneRecord> records) {
boolean hasUsername = SignalStore.account().isRegistered() && SignalStore.account().getUsername() != null;
boolean hasCompleted = MapUtil.mapOrDefault(records, Event.SET_UP_YOUR_USERNAME, MegaphoneRecord::isFinished, false);
long phoneNumberDiscoveryDisabledAt = SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityModeTimestamp();
PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode listingMode = SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode();
boolean hasUsername = SignalStore.account().isRegistered() && SignalStore.account().getUsername() != null;
boolean hasCompleted = MapUtil.mapOrDefault(records, Event.SET_UP_YOUR_USERNAME, MegaphoneRecord::isFinished, false);
long phoneNumberDiscoveryDisabledAt = SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityModeTimestamp();
PhoneNumberDiscoverabilityMode listingMode = SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode();
return !hasUsername &&
listingMode.isUndiscoverable() &&
listingMode == PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE &&
!hasCompleted &&
phoneNumberDiscoveryDisabledAt > 0 &&
(System.currentTimeMillis() - phoneNumberDiscoveryDisabledAt) >= TimeUnit.DAYS.toMillis(3);

View file

@ -286,6 +286,7 @@ public class CreateProfileFragment extends LoggingFragment {
private void presentWhoCanFindMeDescription(PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode phoneNumberListingMode) {
switch (phoneNumberListingMode) {
case DISCOVERABLE:
case UNDECIDED:
binding.whoCanFindMeIcon.setImageResource(R.drawable.symbol_group_24);
binding.whoCanFindMeDescription.setText(R.string.PhoneNumberPrivacy_everyone);
break;

View file

@ -8,8 +8,12 @@ import androidx.lifecycle.Transformations;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.conversation.colors.AvatarColor;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.profiles.ProfileName;
import org.thoughtcrime.securesms.profiles.edit.EditProfileRepository.UploadResult;
@ -22,6 +26,8 @@ import java.util.Objects;
class EditProfileViewModel extends ViewModel {
private static final String TAG = Log.tag(EditProfileViewModel.class);
private final MutableLiveData<String> givenName = new MutableLiveData<>();
private final MutableLiveData<String> familyName = new MutableLiveData<>();
private final LiveData<String> trimmedGivenName = Transformations.map(givenName, StringUtil::trimToVisualBounds);
@ -112,10 +118,6 @@ class EditProfileViewModel extends ViewModel {
return groupId;
}
public boolean canRemoveProfilePhoto() {
return hasAvatar();
}
public SingleLiveEvent<UploadResult> getUploadResult() {
return uploadResult;
}
@ -146,6 +148,11 @@ class EditProfileViewModel extends ViewModel {
String oldDisplayName = isGroup() ? originalDisplayName.getValue() : null;
String oldDescription = isGroup() ? originalDescription : null;
if (!isGroup() && SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode() == PhoneNumberDiscoverabilityMode.UNDECIDED) {
Log.i(TAG, "Phone number discoverability mode is still UNDECIDED. Setting to DISCOVERABLE.");
SignalStore.phoneNumberPrivacy().setPhoneNumberDiscoverabilityMode(PhoneNumberDiscoverabilityMode.DISCOVERABLE);
}
repository.uploadProfile(profileName,
displayName,
!Objects.equals(StringUtil.stripBidiProtection(oldDisplayName), displayName),

View file

@ -17,6 +17,7 @@ class WhoCanFindMeByPhoneNumberRepository {
return when (SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode) {
PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.DISCOVERABLE -> WhoCanFindMeByPhoneNumberState.EVERYONE
PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE -> WhoCanFindMeByPhoneNumberState.NOBODY
PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.UNDECIDED -> WhoCanFindMeByPhoneNumberState.EVERYONE
}
}

View file

@ -3,7 +3,10 @@ package org.thoughtcrime.securesms.registration;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.jobs.StorageSyncJob;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
@ -26,9 +29,17 @@ public final class RegistrationUtil {
{
Log.i(TAG, "Marking registration completed.", new Throwable());
SignalStore.registrationValues().setRegistrationComplete();
ApplicationDependencies.getJobManager().startChain(new StorageSyncJob())
if (SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode() == PhoneNumberDiscoverabilityMode.UNDECIDED) {
Log.w(TAG, "Phone number discoverability mode is still UNDECIDED. Setting to DISCOVERABLE.");
SignalStore.phoneNumberPrivacy().setPhoneNumberDiscoverabilityMode(PhoneNumberDiscoverabilityMode.DISCOVERABLE);
}
ApplicationDependencies.getJobManager().startChain(new RefreshAttributesJob())
.then(new StorageSyncJob())
.then(new DirectoryRefreshJob(false))
.enqueue();
} else if (!SignalStore.registrationValues().isRegistrationComplete()) {
Log.i(TAG, "Registration is not yet complete.", new Throwable());
}

View file

@ -9,6 +9,7 @@ import org.signal.core.util.logging.Log
import org.signal.libsignal.protocol.IdentityKeyPair
import org.thoughtcrime.securesms.AppCapabilities
import org.thoughtcrime.securesms.gcm.FcmUtil
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.pin.SvrWrongPinException
import org.thoughtcrime.securesms.push.AccountManagerFactory
@ -179,7 +180,7 @@ class VerifyAccountRepository(private val context: Application) {
unidentifiedAccessKey = unidentifiedAccessKey,
unrestrictedUnidentifiedAccess = universalUnidentifiedAccess,
capabilities = AppCapabilities.getCapabilities(true),
discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode.isDiscoverable,
discoverableByPhoneNumber = SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode == PhoneNumberDiscoverabilityMode.DISCOVERABLE,
name = null,
pniRegistrationId = registrationData.pniRegistrationId,
recoveryPassword = registrationData.recoveryPassword

View file

@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob;
import org.thoughtcrime.securesms.jobs.StorageSyncJob;
import org.thoughtcrime.securesms.keyvalue.AccountValues;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.payments.Entropy;
import org.thoughtcrime.securesms.recipients.Recipient;
@ -147,7 +148,7 @@ public final class StorageSyncHelper {
.setReadReceiptsEnabled(TextSecurePreferences.isReadReceiptsEnabled(context))
.setSealedSenderIndicatorsEnabled(TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context))
.setLinkPreviewsEnabled(SignalStore.settings().isLinkPreviewsEnabled())
.setUnlistedPhoneNumber(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode().isUndiscoverable())
.setUnlistedPhoneNumber(SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode() == PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE)
.setPhoneNumberSharingMode(StorageSyncModels.localToRemotePhoneNumberSharingMode(SignalStore.phoneNumberPrivacy().getPhoneNumberSharingMode()))
.setPinnedConversations(StorageSyncModels.localToRemotePinnedConversations(pinned))
.setPreferContactAvatars(SignalStore.settings().isPreferSystemContactPhotos())
@ -196,7 +197,7 @@ public final class StorageSyncHelper {
TextSecurePreferences.setTypingIndicatorsEnabled(context, update.getNew().isTypingIndicatorsEnabled());
TextSecurePreferences.setShowUnidentifiedDeliveryIndicatorsEnabled(context, update.getNew().isSealedSenderIndicatorsEnabled());
SignalStore.settings().setLinkPreviewsEnabled(update.getNew().isLinkPreviewsEnabled());
SignalStore.phoneNumberPrivacy().setPhoneNumberDiscoverabilityMode(update.getNew().isPhoneNumberUnlisted() ? PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE : PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.DISCOVERABLE);
SignalStore.phoneNumberPrivacy().setPhoneNumberDiscoverabilityMode(update.getNew().isPhoneNumberUnlisted() ? PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE : PhoneNumberDiscoverabilityMode.DISCOVERABLE);
SignalStore.phoneNumberPrivacy().setPhoneNumberSharingMode(StorageSyncModels.remoteToLocalPhoneNumberSharingMode(update.getNew().getPhoneNumberSharingMode()));
SignalStore.settings().setPreferSystemContactPhotos(update.getNew().isPreferContactAvatars());
SignalStore.paymentsValues().setEnabledAndEntropy(update.getNew().getPayments().isEnabled(), Entropy.fromBytes(update.getNew().getPayments().getEntropy().orElse(null)));