org.whispersystems.signalservice.api.SignalServiceAccountManager Java Examples
The following examples show how to use
org.whispersystems.signalservice.api.SignalServiceAccountManager.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DirectoryHelperV1.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@SuppressLint("CheckResult") private static @NonNull List<RecipientId> refreshDirectory(@NonNull Context context, @NonNull SignalServiceAccountManager accountManager) throws IOException { if (TextUtils.isEmpty(TextSecurePreferences.getLocalNumber(context))) { return Collections.emptyList(); } if (!Permissions.hasAll(context, Manifest.permission.WRITE_CONTACTS)) { return Collections.emptyList(); } RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); Set<String> allRecipientNumbers = recipientDatabase.getAllPhoneNumbers(); Stream<String> eligibleRecipientDatabaseContactNumbers = Stream.of(allRecipientNumbers); Stream<String> eligibleSystemDatabaseContactNumbers = Stream.of(ContactAccessor.getInstance().getAllContactsWithNumbers(context)); Set<String> eligibleContactNumbers = Stream.concat(eligibleRecipientDatabaseContactNumbers, eligibleSystemDatabaseContactNumbers).collect(Collectors.toSet()); Set<String> storedNumbers = Stream.of(allRecipientNumbers).collect(Collectors.toSet()); DirectoryResult directoryResult = getDirectoryResult(context, accountManager, recipientDatabase, storedNumbers, eligibleContactNumbers); return directoryResult.getNewlyActiveRecipients(); }
Example #2
Source File: PushChallengeRequestTest.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@Test public void getPushChallengeBlocking_completes_fast_if_posted_to_event_bus() throws IOException { SignalServiceAccountManager signal = mock(SignalServiceAccountManager.class); doAnswer(invocation -> { AsyncTask.execute(() -> PushChallengeRequest.postChallengeResponse("CHALLENGE")); return null; }).when(signal).requestPushChallenge("token", "+123456"); long startTime = System.currentTimeMillis(); Optional<String> challenge = PushChallengeRequest.getPushChallengeBlocking(signal, Optional.of("token"), "+123456", 500L); long duration = System.currentTimeMillis() - startTime; assertThat(duration, lessThan(500L)); verify(signal).requestPushChallenge("token", "+123456"); verifyNoMoreInteractions(signal); assertTrue(challenge.isPresent()); assertEquals("CHALLENGE", challenge.get()); }
Example #3
Source File: RotateSignedPreKeyJob.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@Override public void onRun() throws Exception { Log.i(TAG, "Rotating signed prekey..."); SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context); SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKey, false); accountManager.setSignedPreKey(signedPreKeyRecord); PreKeyUtil.setActiveSignedPreKeyId(context, signedPreKeyRecord.getId()); TextSecurePreferences.setSignedPreKeyRegistered(context, true); TextSecurePreferences.setSignedPreKeyFailureCount(context, 0); ApplicationDependencies.getJobManager().add(new CleanPreKeysJob()); }
Example #4
Source File: RotateProfileKeyJob.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@Override public void onRun() throws Exception { SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); ProfileKey profileKey = ProfileKeyUtil.createNew(); Recipient self = Recipient.self(); recipientDatabase.setProfileKey(self.getId(), profileKey); try (StreamDetails avatarStream = AvatarHelper.getSelfProfileAvatarStream(context)) { if (FeatureFlags.versionedProfiles()) { accountManager.setVersionedProfile(self.getUuid().get(), profileKey, Recipient.self().getProfileName().serialize(), avatarStream); } else { accountManager.setProfileName(profileKey, Recipient.self().getProfileName().serialize()); accountManager.setProfileAvatar(profileKey, avatarStream); } } ApplicationDependencies.getJobManager().add(new RefreshAttributesJob()); updateProfileKeyOnAllV2Groups(); }
Example #5
Source File: CreateSignedPreKeyJob.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@Override public void onRun() throws IOException { if (TextSecurePreferences.isSignedPreKeyRegistered(context)) { Log.w(TAG, "Signed prekey already registered..."); return; } if (!TextSecurePreferences.isPushRegistered(context)) { Log.w(TAG, "Not yet registered..."); return; } SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); IdentityKeyPair identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context); SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKeyPair, true); accountManager.setSignedPreKey(signedPreKeyRecord); TextSecurePreferences.setSignedPreKeyRegistered(context, true); }
Example #6
Source File: AdvancedPreferenceFragment.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@Override protected Integer doInBackground(Void... params) { try { Context context = getActivity(); SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); try { accountManager.setGcmId(Optional.<String>absent()); } catch (AuthorizationFailedException e) { Log.w(TAG, e); } if (!TextSecurePreferences.isFcmDisabled(context)) { FirebaseInstanceId.getInstance().deleteInstanceId(); } return SUCCESS; } catch (IOException ioe) { Log.w(TAG, ioe); return NETWORK_ERROR; } }
Example #7
Source File: Manager.java From signald with GNU General Public License v3.0 | 6 votes |
public void finishDeviceLink(String deviceName) throws IOException, InvalidKeyException, TimeoutException, UserAlreadyExists { accountData.signalingKey = Util.getSecret(52); SignalServiceAccountManager.NewDeviceRegistrationReturn ret = accountManager.finishNewDeviceRegistration(accountData.axolotlStore.identityKeyStore.getIdentityKeyPair(), accountData.signalingKey, false, true, accountData.axolotlStore.identityKeyStore.getLocalRegistrationId(), deviceName); accountData.deviceId = ret.getDeviceId(); accountData.username = ret.getNumber(); // TODO do this check before actually registering if (userExists()) { throw new UserAlreadyExists(accountData.username, getFileName()); } accountData.axolotlStore = new SignalProtocolStore(ret.getIdentity(), accountData.axolotlStore.identityKeyStore.getLocalRegistrationId()); accountData.registered = true; refreshPreKeys(); accountData.init(); requestSyncGroups(); requestSyncContacts(); accountData.save(); managers.put(accountData.username, this); logger.info("Successfully finished linked to " + Util.redact(accountData.username) + " as device #" + accountData.deviceId); }
Example #8
Source File: AccountManagerFactory.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
/** * Should only be used during registration when you haven't yet been assigned a UUID. */ public static @NonNull SignalServiceAccountManager createUnauthenticated(@NonNull Context context, @NonNull String number, @NonNull String password) { if (new SignalServiceNetworkAccess(context).isCensored(number)) { SignalExecutors.BOUNDED.execute(() -> { try { ProviderInstaller.installIfNeeded(context); } catch (Throwable t) { Log.w(TAG, t); } }); } return new SignalServiceAccountManager(new SignalServiceNetworkAccess(context).getConfiguration(number), null, number, password, BuildConfig.SIGNAL_AGENT); }
Example #9
Source File: AccountManagerFactory.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
public static @NonNull SignalServiceAccountManager createAuthenticated(@NonNull Context context, @NonNull UUID uuid, @NonNull String number, @NonNull String password) { if (new SignalServiceNetworkAccess(context).isCensored(number)) { SignalExecutors.BOUNDED.execute(() -> { try { ProviderInstaller.installIfNeeded(context); } catch (Throwable t) { Log.w(TAG, t); } }); } return new SignalServiceAccountManager(new SignalServiceNetworkAccess(context).getConfiguration(number), uuid, number, password, BuildConfig.SIGNAL_AGENT); }
Example #10
Source File: ApplicationDependencies.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
public static synchronized @NonNull SignalServiceAccountManager getSignalServiceAccountManager() { assertInitialization(); if (accountManager == null) { accountManager = provider.provideSignalServiceAccountManager(); } return accountManager; }
Example #11
Source File: SignalBot.java From signal-bot with GNU General Public License v3.0 | 5 votes |
public void verify(String verificationCode) throws IOException { String username = prefs.get("LOCAL_USERNAME", null); String password = prefs.get("LOCAL_PASSWORD", null); logger.info("Verifying user " + username + " with code " + verificationCode + "..."); String code = verificationCode.replace("-", ""); int registrationId = KeyHelper.generateRegistrationId(false); prefs.putInt("REGISTRATION_ID", registrationId); byte[] profileKey = Util.getSecretBytes(32); byte[] unidentifiedAccessKey = UnidentifiedAccess.deriveAccessKeyFrom(profileKey); accountManager = new SignalServiceAccountManager(config, username, password, USER_AGENT); accountManager.verifyAccountWithCode(code, null, registrationId, true, null, unidentifiedAccessKey, false); }
Example #12
Source File: SignalBot.java From signal-bot with GNU General Public License v3.0 | 5 votes |
public void register(String username) throws IOException, BackingStoreException { logger.info("Sending verification SMS to " + username + "."); prefs.clear(); String password = Base64.encodeBytes(Util.getSecretBytes(18)); prefs.put("LOCAL_USERNAME", username); prefs.put("LOCAL_PASSWORD", password); accountManager = new SignalServiceAccountManager(config, username, password, USER_AGENT); accountManager.requestSmsVerificationCode(false); }
Example #13
Source File: SignalBot.java From signal-bot with GNU General Public License v3.0 | 5 votes |
public void listen() throws IOException, InvalidKeyException { String username = prefs.get("LOCAL_USERNAME", null); String password = prefs.get("LOCAL_PASSWORD", null); logger.info("Generating keys for " + username + "..."); IdentityKeyPair identityKeyPair = KeyHelper.generateIdentityKeyPair(); int registrationId = prefs.getInt("REGISTRATION_ID", -1); this.protocolStore = new InMemorySignalProtocolStore(identityKeyPair, registrationId); accountManager = new SignalServiceAccountManager(config, username, password, USER_AGENT); refreshPreKeys(identityKeyPair); logger.info("Starting message listener..."); messageRetrieverThread.start(); // TODO refresh keys job }
Example #14
Source File: PushChallengeRequestTest.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Test public void getPushChallengeBlocking_returns_absent_if_no_fcm_token_supplied() { SignalServiceAccountManager signal = mock(SignalServiceAccountManager.class); Optional<String> challenge = PushChallengeRequest.getPushChallengeBlocking(signal, Optional.absent(), "+123456", 500L); verifyZeroInteractions(signal); assertFalse(challenge.isPresent()); }
Example #15
Source File: PushChallengeRequestTest.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Test public void getPushChallengeBlocking_returns_fast_if_no_fcm_token_supplied() { SignalServiceAccountManager signal = mock(SignalServiceAccountManager.class); long startTime = System.currentTimeMillis(); PushChallengeRequest.getPushChallengeBlocking(signal, Optional.absent(), "+123456", 500L); long duration = System.currentTimeMillis() - startTime; assertThat(duration, lessThan(500L)); }
Example #16
Source File: PushChallengeRequestTest.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Test public void getPushChallengeBlocking_waits_for_specified_period() { SignalServiceAccountManager signal = mock(SignalServiceAccountManager.class); long startTime = System.currentTimeMillis(); PushChallengeRequest.getPushChallengeBlocking(signal, Optional.of("token"), "+123456", 250L); long duration = System.currentTimeMillis() - startTime; assertThat(duration, greaterThanOrEqualTo(250L)); }
Example #17
Source File: PushChallengeRequestTest.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Test public void getPushChallengeBlocking_returns_absent_if_times_out() { SignalServiceAccountManager signal = mock(SignalServiceAccountManager.class); Optional<String> challenge = PushChallengeRequest.getPushChallengeBlocking(signal, Optional.of("token"), "+123456", 50L); assertFalse(challenge.isPresent()); }
Example #18
Source File: ApplicationDependencyProvider.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Override public @NonNull SignalServiceAccountManager provideSignalServiceAccountManager() { return new SignalServiceAccountManager(networkAccess.getConfiguration(context), new DynamicCredentialsProvider(context), BuildConfig.SIGNAL_AGENT, provideGroupsV2Operations()); }
Example #19
Source File: Manager.java From signald with GNU General Public License v3.0 | 5 votes |
public void init() throws IOException { accountData = AccountData.load(new File(getFileName())); accountManager = new SignalServiceAccountManager(serviceConfiguration, accountData.username, accountData.password, accountData.deviceId, USER_AGENT, sleepTimer); try { if (accountData.registered && accountManager.getPreKeysCount() < PREKEY_MINIMUM_COUNT) { refreshPreKeys(); accountData.save(); } } catch (AuthorizationFailedException e) { logger.warn("Authorization failed, was the number registered elsewhere?"); accountData.registered = false; } }
Example #20
Source File: PushChallengeRequest.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private Request(@NonNull SignalServiceAccountManager accountManager, @NonNull String fcmToken, @NonNull String e164number, long timeoutMs) { this.latch = new CountDownLatch(1); this.challenge = new AtomicReference<>(); this.accountManager = accountManager; this.fcmToken = fcmToken; this.e164number = e164number; this.timeoutMs = timeoutMs; }
Example #21
Source File: RotateCertificateJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Override public void onRun() throws IOException { if (!TextSecurePreferences.isPushRegistered(context)) { Log.w(TAG, "Not yet registered. Ignoring."); return; } synchronized (RotateCertificateJob.class) { SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); byte[] certificate = accountManager.getSenderCertificate(); TextSecurePreferences.setUnidentifiedAccessCertificate(context, certificate); } }
Example #22
Source File: ProvisioningManager.java From signal-cli with GNU General Public License v3.0 | 5 votes |
public ProvisioningManager(String settingsPath, SignalServiceConfiguration serviceConfiguration, String userAgent) { this.pathConfig = PathConfig.createDefault(settingsPath); this.serviceConfiguration = serviceConfiguration; this.userAgent = userAgent; identityKey = KeyHelper.generateIdentityKeyPair(); registrationId = KeyHelper.generateRegistrationId(false); password = KeyUtils.createPassword(); final SleepTimer timer = new UptimeSleepTimer(); accountManager = new SignalServiceAccountManager(serviceConfiguration, null, null, password, SignalServiceAddress.DEFAULT_DEVICE_ID, userAgent, timer); }
Example #23
Source File: RefreshPreKeysJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Override public void onRun() throws IOException { if (!TextSecurePreferences.isPushRegistered(context)) { Log.w(TAG, "Not registered. Skipping."); return; } SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); int availableKeys = accountManager.getPreKeysCount(); Log.i(TAG, "Available keys: " + availableKeys); if (availableKeys >= PREKEY_MINIMUM && TextSecurePreferences.isSignedPreKeyRegistered(context)) { Log.i(TAG, "Available keys sufficient."); SignalStore.setLastPrekeyRefreshTime(System.currentTimeMillis()); return; } List<PreKeyRecord> preKeyRecords = PreKeyUtil.generatePreKeys(context); IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context); SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKey, false); Log.i(TAG, "Registering new prekeys..."); accountManager.setPreKeys(identityKey.getPublicKey(), signedPreKeyRecord, preKeyRecords); PreKeyUtil.setActiveSignedPreKeyId(context, signedPreKeyRecord.getId()); TextSecurePreferences.setSignedPreKeyRegistered(context, true); ApplicationDependencies.getJobManager().add(new CleanPreKeysJob()); SignalStore.setLastPrekeyRefreshTime(System.currentTimeMillis()); Log.i(TAG, "Successfully refreshed prekeys."); }
Example #24
Source File: Manager.java From signald with GNU General Public License v3.0 | 5 votes |
public void register(boolean voiceVerification, Optional<String> captcha) throws IOException { accountData.password = Util.getSecret(18); accountManager = new SignalServiceAccountManager(serviceConfiguration, accountData.username, accountData.password, USER_AGENT, sleepTimer); if (voiceVerification) { accountManager.requestVoiceVerificationCode(Locale.getDefault(), captcha, Optional.absent()); // TODO: Allow requester to set the locale } else { accountManager.requestSmsVerificationCode(true, captcha, Optional.absent()); // TODO: Allow requester to set challenge } accountData.registered = false; accountData.init(); accountData.save(); }
Example #25
Source File: RefreshAttributesJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@Override public void onRun() throws IOException { if (!TextSecurePreferences.isPushRegistered(context) || TextSecurePreferences.getLocalNumber(context) == null) { Log.w(TAG, "Not yet registered. Skipping."); return; } int registrationId = TextSecurePreferences.getLocalRegistrationId(context); boolean fetchesMessages = TextSecurePreferences.isFcmDisabled(context); byte[] unidentifiedAccessKey = UnidentifiedAccess.deriveAccessKeyFrom(ProfileKeyUtil.getSelfProfileKey()); boolean universalUnidentifiedAccess = TextSecurePreferences.isUniversalUnidentifiedAccess(context); String registrationLockV1 = null; String registrationLockV2 = null; KbsValues kbsValues = SignalStore.kbsValues(); if (kbsValues.isV2RegistrationLockEnabled()) { registrationLockV2 = kbsValues.getRegistrationLockToken(); } else if (TextSecurePreferences.isV1RegistrationLockEnabled(context)) { //noinspection deprecation Ok to read here as they have not migrated registrationLockV1 = TextSecurePreferences.getDeprecatedV1RegistrationLockPin(context); } Log.i(TAG, "Calling setAccountAttributes() reglockV1? " + !TextUtils.isEmpty(registrationLockV1) + ", reglockV2? " + !TextUtils.isEmpty(registrationLockV2) + ", pin? " + kbsValues.hasPin()); SignalServiceAccountManager signalAccountManager = ApplicationDependencies.getSignalServiceAccountManager(); signalAccountManager.setAccountAttributes(null, registrationId, fetchesMessages, registrationLockV1, registrationLockV2, unidentifiedAccessKey, universalUnidentifiedAccess, AppCapabilities.getCapabilities(kbsValues.hasPin())); }
Example #26
Source File: Manager.java From signald with GNU General Public License v3.0 | 5 votes |
public URI getDeviceLinkUri() throws TimeoutException, IOException { accountData.password = Util.getSecret(18); accountManager = new SignalServiceAccountManager(serviceConfiguration, accountData.username, accountData.password, USER_AGENT, sleepTimer); String uuid = accountManager.getNewDeviceUuid(); accountData.registered = false; try { return new URI("tsdevice:/?uuid=" + URLEncoder.encode(uuid, "utf-8") + "&pub_key=" + URLEncoder.encode(Base64.encodeBytesWithoutPadding(accountData.axolotlStore.identityKeyStore.getIdentityKeyPair().getPublicKey().serialize()), "utf-8")); } catch (URISyntaxException e) { // Shouldn't happen return null; } }
Example #27
Source File: PushChallengeRequest.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
/** * Requests a push challenge and waits for the response. * <p> * Blocks the current thread for up to {@param timeoutMs} milliseconds. * * @param accountManager Account manager to request the push from. * @param fcmToken Optional FCM token. If not present will return absent. * @param e164number Local number. * @param timeoutMs Timeout in milliseconds * @return Either returns a challenge, or absent. */ @WorkerThread public static Optional<String> getPushChallengeBlocking(@NonNull SignalServiceAccountManager accountManager, @NonNull Optional<String> fcmToken, @NonNull String e164number, long timeoutMs) { if (!fcmToken.isPresent()) { Log.w(TAG, "Push challenge not requested, as no FCM token was present"); return Optional.absent(); } long startTime = System.currentTimeMillis(); Log.i(TAG, "Requesting a push challenge"); Request request = new Request(accountManager, fcmToken.get(), e164number, timeoutMs); Optional<String> challenge = request.requestAndReceiveChallengeBlocking(); long duration = System.currentTimeMillis() - startTime; if (challenge.isPresent()) { Log.i(TAG, String.format(Locale.US, "Received a push challenge \"%s\" in %d ms", challenge.get(), duration)); } else { Log.w(TAG, String.format(Locale.US, "Did not received a push challenge in %d ms", duration)); } return challenge; }
Example #28
Source File: ProvisioningManager.java From signal-cli with GNU General Public License v3.0 | 4 votes |
public String finishDeviceLink(String deviceName) throws IOException, InvalidKeyException, TimeoutException, UserAlreadyExists { String signalingKey = KeyUtils.createSignalingKey(); SignalServiceAccountManager.NewDeviceRegistrationReturn ret = accountManager.finishNewDeviceRegistration(identityKey, signalingKey, false, true, registrationId, deviceName); String username = ret.getNumber(); // TODO do this check before actually registering if (SignalAccount.userExists(pathConfig.getDataPath(), username)) { throw new UserAlreadyExists(username, SignalAccount.getFileName(pathConfig.getDataPath(), username)); } // Create new account with the synced identity byte[] profileKeyBytes = ret.getProfileKey(); ProfileKey profileKey; if (profileKeyBytes == null) { profileKey = KeyUtils.createProfileKey(); } else { try { profileKey = new ProfileKey(profileKeyBytes); } catch (InvalidInputException e) { throw new IOException("Received invalid profileKey", e); } } try (SignalAccount account = SignalAccount.createLinkedAccount(pathConfig.getDataPath(), username, ret.getUuid(), password, ret.getDeviceId(), ret.getIdentity(), registrationId, signalingKey, profileKey)) { account.save(); try (Manager m = new Manager(account, pathConfig, serviceConfiguration, userAgent)) { m.refreshPreKeys(); m.requestSyncGroups(); m.requestSyncContacts(); m.requestSyncBlocked(); m.requestSyncConfiguration(); m.saveAccount(); } } return username; }
Example #29
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 4 votes |
private SignalServiceAccountManager createSignalServiceAccountManager() { return new SignalServiceAccountManager(serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(), account.getDeviceId(), userAgent, timer); }
Example #30
Source File: StorageForcePushJob.java From mollyim-android with GNU General Public License v3.0 | 4 votes |
@Override protected void onRun() throws IOException, RetryLaterException { StorageKey storageServiceKey = SignalStore.storageServiceValues().getOrCreateStorageKey(); SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); RecipientDatabase recipientDatabase = DatabaseFactory.getRecipientDatabase(context); StorageKeyDatabase storageKeyDatabase = DatabaseFactory.getStorageKeyDatabase(context); long currentVersion = accountManager.getStorageManifestVersion(); Map<RecipientId, StorageId> oldContactStorageIds = recipientDatabase.getContactStorageSyncIdsMap(); long newVersion = currentVersion + 1; Map<RecipientId, StorageId> newContactStorageIds = generateContactStorageIds(oldContactStorageIds); Set<RecipientId> archivedRecipients = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients(); List<SignalStorageRecord> inserts = Stream.of(oldContactStorageIds.keySet()) .map(recipientDatabase::getRecipientSettingsForSync) .withoutNulls() .map(s -> StorageSyncModels.localToRemoteRecord(s, Objects.requireNonNull(newContactStorageIds.get(s.getId())).getRaw(), archivedRecipients)) .toList(); SignalStorageRecord accountRecord = StorageSyncHelper.buildAccountRecord(context, Recipient.self().fresh()); List<StorageId> allNewStorageIds = new ArrayList<>(newContactStorageIds.values()); inserts.add(accountRecord); allNewStorageIds.add(accountRecord.getId()); SignalStorageManifest manifest = new SignalStorageManifest(newVersion, allNewStorageIds); StorageSyncValidations.validateForcePush(manifest, inserts); try { if (newVersion > 1) { Log.i(TAG, String.format(Locale.ENGLISH, "Force-pushing data. Inserting %d keys.", inserts.size())); if (accountManager.resetStorageRecords(storageServiceKey, manifest, inserts).isPresent()) { Log.w(TAG, "Hit a conflict. Trying again."); throw new RetryLaterException(); } } else { Log.i(TAG, String.format(Locale.ENGLISH, "First version, normal push. Inserting %d keys.", inserts.size())); if (accountManager.writeStorageRecords(storageServiceKey, manifest, inserts, Collections.emptyList()).isPresent()) { Log.w(TAG, "Hit a conflict. Trying again."); throw new RetryLaterException(); } } } catch (InvalidKeyException e) { Log.w(TAG, "Hit an invalid key exception, which likely indicates a conflict."); throw new RetryLaterException(e); } Log.i(TAG, "Force push succeeded. Updating local manifest version to: " + newVersion); TextSecurePreferences.setStorageManifestVersion(context, newVersion); recipientDatabase.applyStorageIdUpdates(newContactStorageIds); recipientDatabase.applyStorageIdUpdates(Collections.singletonMap(Recipient.self().getId(), accountRecord.getId())); storageKeyDatabase.deleteAll(); }