diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 6da928671f..7d57618918 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -56,6 +56,7 @@ import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; +import org.thoughtcrime.securesms.registration.RegistrationUtil; import org.thoughtcrime.securesms.revealable.ViewOnceMessageManager; import org.thoughtcrime.securesms.ringrtc.RingRtcLogger; import org.thoughtcrime.securesms.service.DirectoryRefreshListener; @@ -135,6 +136,7 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi NotificationChannels.create(this); RefreshPreKeysJob.scheduleIfNecessary(); StorageSyncHelper.scheduleRoutineSync(); + RegistrationUtil.markRegistrationPossiblyComplete(); ProcessLifecycleOwner.get().getLifecycle().addObserver(this); if (Build.VERSION.SDK_INT < 21) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java index 84fd5bf970..e1b356c963 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java @@ -215,7 +215,7 @@ public class StorageSyncJob extends BaseJob { archivedRecipients); if (localWriteResult.isPresent()) { - Log.i(TAG, String.format(Locale.ENGLISH, "[Local Changes] Local changes present. %d updates, %d inserts, %d deletes, account update: %b, account insert %b.", pendingUpdates.size(), pendingInsertions.size(), pendingDeletions.size(), pendingAccountUpdate.isPresent(), pendingAccountInsert.isPresent())); + Log.i(TAG, String.format(Locale.ENGLISH, "[Local Changes] Local changes present. %d updates, %d inserts, %d deletes, account update: %b, account insert: %b.", pendingUpdates.size(), pendingInsertions.size(), pendingDeletions.size(), pendingAccountUpdate.isPresent(), pendingAccountInsert.isPresent())); WriteOperationResult localWrite = localWriteResult.get().getWriteResult(); StorageSyncValidations.validate(localWrite); diff --git a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java index 14a67c68c4..842aa422e8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreEntryFragment.java @@ -26,15 +26,18 @@ import com.dd.CircularProgressButton; import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.MainActivity; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.lock.v2.KbsConstants; import org.thoughtcrime.securesms.lock.v2.PinKeyboardType; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.profiles.AvatarHelper; import org.thoughtcrime.securesms.profiles.edit.EditProfileActivity; import org.thoughtcrime.securesms.recipients.Recipient; +import org.thoughtcrime.securesms.registration.RegistrationUtil; import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.ViewUtil; +import org.whispersystems.signalservice.internal.storage.protos.SignalStorage; import java.util.Locale; @@ -232,6 +235,7 @@ public class PinRestoreEntryFragment extends Fragment { profile.putExtra("next_intent", main); startActivity(profile); } else { + RegistrationUtil.markRegistrationPossiblyComplete(); startActivity(new Intent(activity, MainActivity.class)); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationUtil.java index 43ed573847..35acdcad30 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationUtil.java @@ -4,6 +4,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.storage.StorageSyncHelper; +import org.whispersystems.signalservice.internal.storage.protos.SignalStorage; public final class RegistrationUtil { @@ -17,10 +18,12 @@ public final class RegistrationUtil { * requirements are met. */ public static void markRegistrationPossiblyComplete() { - if (SignalStore.kbsValues().hasPin() && !Recipient.self().getProfileName().isEmpty()) { + if (!SignalStore.registrationValues().isRegistrationComplete() && SignalStore.kbsValues().hasPin() && !Recipient.self().getProfileName().isEmpty()) { Log.i(TAG, "Marking registration completed.", new Throwable()); SignalStore.registrationValues().setRegistrationComplete(); StorageSyncHelper.scheduleSyncForDataChange(); + } else if (!SignalStore.registrationValues().isRegistrationComplete()) { + Log.i(TAG, "Registration is not yet complete.", new Throwable()); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java index 307fb85953..124d980b63 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/StorageSyncHelper.java @@ -31,6 +31,7 @@ import org.whispersystems.signalservice.api.storage.SignalStorageManifest; import org.whispersystems.signalservice.api.storage.SignalStorageRecord; import org.whispersystems.signalservice.api.storage.StorageId; import org.whispersystems.signalservice.api.util.OptionalUtil; +import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -83,8 +84,31 @@ public final class StorageSyncHelper { @NonNull Optional accountInsert, @NonNull Set archivedRecipients) { + int accountCount = Stream.of(currentLocalKeys) + .filter(id -> id.getType() == ManifestRecord.Identifier.Type.ACCOUNT_VALUE) + .toList() + .size(); + + if (accountCount > 1) { + throw new MultipleExistingAccountsException(); + } + + Optional accountId = Optional.fromNullable(Stream.of(currentLocalKeys) + .filter(id -> id.getType() == ManifestRecord.Identifier.Type.ACCOUNT_VALUE) + .findFirst() + .orElse(null)); + + + if (accountId.isPresent() && accountInsert.isPresent() && !accountInsert.get().getId().equals(accountId.get())) { + throw new InvalidAccountInsertException(); + } + + if (accountId.isPresent() && accountUpdate.isPresent() && !accountUpdate.get().getId().equals(accountId.get())) { + throw new InvalidAccountUpdateException(); + } + if (accountUpdate.isPresent() && accountInsert.isPresent()) { - throw new AssertionError("Cannot update and insert an account at the same time!"); + throw new InvalidAccountDualInsertUpdateException(); } Set completeIds = new LinkedHashSet<>(currentLocalKeys); @@ -631,4 +655,9 @@ public final class StorageSyncHelper { interface KeyGenerator { @NonNull byte[] generate(); } + + private static final class MultipleExistingAccountsException extends IllegalArgumentException {} + private static final class InvalidAccountInsertException extends IllegalArgumentException {} + private static final class InvalidAccountUpdateException extends IllegalArgumentException {} + private static final class InvalidAccountDualInsertUpdateException extends IllegalArgumentException {} }