use of org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob in project Signal-Android by WhisperSystems.
the class DirectoryHelper method refreshNumbers.
@WorkerThread
private static void refreshNumbers(@NonNull Context context, @NonNull Set<String> databaseNumbers, @NonNull Set<String> systemNumbers, boolean notifyOfNewUsers, boolean removeSystemContactEntryForMissing) throws IOException {
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
Set<String> allNumbers = SetUtil.union(databaseNumbers, systemNumbers);
if (allNumbers.isEmpty()) {
Log.w(TAG, "No numbers to refresh!");
return;
}
Stopwatch stopwatch = new Stopwatch("refresh");
DirectoryResult result;
if (FeatureFlags.cdsh()) {
result = ContactDiscoveryV3.getDirectoryResult(databaseNumbers, systemNumbers);
} else {
result = ContactDiscoveryV2.getDirectoryResult(context, databaseNumbers, systemNumbers);
}
stopwatch.split("network");
if (result.getNumberRewrites().size() > 0) {
Log.i(TAG, "[getDirectoryResult] Need to rewrite some numbers.");
recipientDatabase.updatePhoneNumbers(result.getNumberRewrites());
}
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)).map(recipientDatabase::getOrInsertFromE164).collect(Collectors.toSet());
stopwatch.split("process-cds");
UnlistedResult unlistedResult = filterForUnlistedUsers(context, inactiveIds);
inactiveIds.removeAll(unlistedResult.getPossiblyActive());
if (unlistedResult.getRetries().size() > 0) {
Log.i(TAG, "Some profile fetches failed to resolve. Assuming not-inactive for now and scheduling a retry.");
RetrieveProfileJob.enqueue(unlistedResult.getRetries());
}
stopwatch.split("handle-unlisted");
Set<RecipientId> preExistingRegisteredUsers = new HashSet<>(recipientDatabase.getRegistered());
recipientDatabase.bulkUpdatedRegisteredStatus(aciMap, inactiveIds);
stopwatch.split("update-registered");
updateContactsDatabase(context, activeIds, removeSystemContactEntryForMissing, result.getNumberRewrites());
stopwatch.split("contacts-db");
if (TextSecurePreferences.isMultiDevice(context)) {
ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob());
}
if (TextSecurePreferences.hasSuccessfullyRetrievedDirectory(context) && notifyOfNewUsers) {
Set<RecipientId> systemContacts = new HashSet<>(recipientDatabase.getSystemContacts());
Set<RecipientId> newlyRegisteredSystemContacts = new HashSet<>(activeIds);
newlyRegisteredSystemContacts.removeAll(preExistingRegisteredUsers);
newlyRegisteredSystemContacts.retainAll(systemContacts);
notifyNewUsers(context, newlyRegisteredSystemContacts);
} else {
TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true);
}
stopwatch.stop(TAG);
}
use of org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob in project Signal-Android by WhisperSystems.
the class DirectoryHelper method refreshDirectoryFor.
@WorkerThread
public static RegisteredState refreshDirectoryFor(@NonNull Context context, @NonNull Recipient recipient, boolean notifyOfNewUsers) throws IOException {
Stopwatch stopwatch = new Stopwatch("single");
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
RegisteredState originalRegisteredState = recipient.resolve().getRegistered();
RegisteredState newRegisteredState;
if (recipient.hasServiceId() && !recipient.hasE164()) {
boolean isRegistered = ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId());
stopwatch.split("aci-network");
if (isRegistered) {
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
if (idChanged) {
Log.w(TAG, "ID changed during refresh by UUID.");
}
} else {
recipientDatabase.markUnregistered(recipient.getId());
}
stopwatch.split("aci-disk");
stopwatch.stop(TAG);
return isRegistered ? RegisteredState.REGISTERED : RegisteredState.NOT_REGISTERED;
}
if (!recipient.getE164().isPresent()) {
Log.w(TAG, "No ACI or E164?");
return RegisteredState.NOT_REGISTERED;
}
DirectoryResult result = ContactDiscoveryV2.getDirectoryResult(context, recipient.getE164().get());
stopwatch.split("e164-network");
if (result.getNumberRewrites().size() > 0) {
Log.i(TAG, "[getDirectoryResult] Need to rewrite some numbers.");
recipientDatabase.updatePhoneNumbers(result.getNumberRewrites());
}
if (result.getRegisteredNumbers().size() > 0) {
ACI aci = result.getRegisteredNumbers().values().iterator().next();
if (aci != null) {
boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), aci);
if (idChanged) {
recipient = Recipient.resolved(recipientDatabase.getByServiceId(aci).get());
}
} else {
Log.w(TAG, "Registered number set had a null ACI!");
}
} else if (recipient.hasServiceId() && recipient.isRegistered() && hasCommunicatedWith(recipient)) {
if (ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId())) {
recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
} else {
recipientDatabase.markUnregistered(recipient.getId());
}
stopwatch.split("e164-unlisted-network");
} else {
recipientDatabase.markUnregistered(recipient.getId());
}
if (Permissions.hasAll(context, Manifest.permission.WRITE_CONTACTS)) {
updateContactsDatabase(context, Collections.singletonList(recipient.getId()), false, result.getNumberRewrites());
}
newRegisteredState = result.getRegisteredNumbers().size() > 0 ? RegisteredState.REGISTERED : RegisteredState.NOT_REGISTERED;
if (newRegisteredState != originalRegisteredState) {
ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob());
ApplicationDependencies.getJobManager().add(new StorageSyncJob());
if (notifyOfNewUsers && newRegisteredState == RegisteredState.REGISTERED && recipient.resolve().isSystemContact()) {
notifyNewUsers(context, Collections.singletonList(recipient.getId()));
}
StorageSyncHelper.scheduleSyncForDataChange();
}
stopwatch.split("e164-disk");
stopwatch.stop(TAG);
return newRegisteredState;
}
use of org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob in project Signal-Android by WhisperSystems.
the class MessageContentProcessor method handleSynchronizeRequestMessage.
private void handleSynchronizeRequestMessage(@NonNull RequestMessage message, long envelopeTimestamp) {
if (SignalStore.account().isPrimaryDevice()) {
log(envelopeTimestamp, "Synchronize request message.");
} else {
log(envelopeTimestamp, "Linked device ignoring synchronize request message.");
return;
}
if (message.isContactsRequest()) {
ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob(true));
}
if (message.isGroupsRequest()) {
ApplicationDependencies.getJobManager().add(new MultiDeviceGroupUpdateJob());
}
if (message.isBlockedListRequest()) {
ApplicationDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob());
}
if (message.isConfigurationRequest()) {
ApplicationDependencies.getJobManager().add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(context), TextSecurePreferences.isTypingIndicatorsEnabled(context), TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), SignalStore.settings().isLinkPreviewsEnabled()));
ApplicationDependencies.getJobManager().add(new MultiDeviceStickerPackSyncJob());
}
if (message.isKeysRequest()) {
ApplicationDependencies.getJobManager().add(new MultiDeviceKeysUpdateJob());
}
if (message.isPniIdentityRequest()) {
ApplicationDependencies.getJobManager().add(new MultiDevicePniIdentityUpdateJob());
}
}
use of org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob in project Signal-Android by WhisperSystems.
the class RecipientIdJobMigrationTest method migrate_multiDeviceContactUpdateJob.
@Test
public void migrate_multiDeviceContactUpdateJob() throws Exception {
JobData testData = new JobData("MultiDeviceContactUpdateJob", "MultiDeviceContactUpdateJob", new Data.Builder().putBoolean("force_sync", false).putString("address", "+16101234567").build());
mockRecipientResolve("+16101234567", 1);
RecipientIdJobMigration subject = new RecipientIdJobMigration(mock(Application.class));
JobData converted = subject.migrate(testData);
assertEquals("MultiDeviceContactUpdateJob", converted.getFactoryKey());
assertEquals("MultiDeviceContactUpdateJob", converted.getQueueKey());
assertFalse(converted.getData().getBoolean("force_sync"));
assertFalse(converted.getData().hasString("address"));
assertEquals("1", converted.getData().getString("recipient"));
new MultiDeviceContactUpdateJob.Factory().create(mock(Job.Parameters.class), converted.getData());
}
use of org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob in project Signal-Android by WhisperSystems.
the class DirectoryHelper method refreshDirectoryFor.
public static UserCapabilities refreshDirectoryFor(@NonNull Context context, @Nullable MasterSecret masterSecret, @NonNull Recipients recipients, @NonNull String localNumber) throws IOException {
try {
TextSecureDirectory directory = TextSecureDirectory.getInstance(context);
SignalServiceAccountManager accountManager = AccountManagerFactory.createManager(context);
String number = Util.canonicalizeNumber(context, recipients.getPrimaryRecipient().getNumber());
Optional<ContactTokenDetails> details = accountManager.getContact(number);
if (details.isPresent()) {
directory.setNumber(details.get(), true);
RefreshResult result = updateContactsDatabase(context, localNumber, details.get());
if (!result.getNewUsers().isEmpty() && TextSecurePreferences.isMultiDevice(context)) {
ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceContactUpdateJob(context));
}
if (!result.isFresh()) {
notifyNewUsers(context, masterSecret, result.getNewUsers());
}
return new UserCapabilities(Capability.SUPPORTED, details.get().isVoice() ? Capability.SUPPORTED : Capability.UNSUPPORTED, details.get().isVideo() ? Capability.SUPPORTED : Capability.UNSUPPORTED);
} else {
ContactTokenDetails absent = new ContactTokenDetails();
absent.setNumber(number);
directory.setNumber(absent, false);
return UserCapabilities.UNSUPPORTED;
}
} catch (InvalidNumberException e) {
Log.w(TAG, e);
return UserCapabilities.UNSUPPORTED;
}
}
Aggregations