use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.
the class StorageSyncJob method buildLocalStorageRecords.
@NonNull
private static List<SignalStorageRecord> buildLocalStorageRecords(@NonNull Context context, @NonNull Recipient self, @NonNull Collection<StorageId> ids) {
if (ids.isEmpty()) {
return Collections.emptyList();
}
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
UnknownStorageIdDatabase storageIdDatabase = SignalDatabase.unknownStorageIds();
List<SignalStorageRecord> records = new ArrayList<>(ids.size());
for (StorageId id : ids) {
switch(id.getType()) {
case ManifestRecord.Identifier.Type.CONTACT_VALUE:
case ManifestRecord.Identifier.Type.GROUPV1_VALUE:
case ManifestRecord.Identifier.Type.GROUPV2_VALUE:
RecipientRecord settings = recipientDatabase.getByStorageId(id.getRaw());
if (settings != null) {
if (settings.getGroupType() == RecipientDatabase.GroupType.SIGNAL_V2 && settings.getSyncExtras().getGroupMasterKey() == null) {
throw new MissingGv2MasterKeyError();
} else {
records.add(StorageSyncModels.localToRemoteRecord(settings));
}
} else {
throw new MissingRecipientModelError("Missing local recipient model! Type: " + id.getType());
}
break;
case ManifestRecord.Identifier.Type.ACCOUNT_VALUE:
if (!Arrays.equals(self.getStorageServiceId(), id.getRaw())) {
throw new AssertionError("Local storage ID doesn't match self!");
}
records.add(StorageSyncHelper.buildAccountRecord(context, self));
break;
default:
SignalStorageRecord unknown = storageIdDatabase.getById(id.getRaw());
if (unknown != null) {
records.add(unknown);
} else {
throw new MissingUnknownModelError("Missing local unknown model! Type: " + id.getType());
}
break;
}
}
return records;
}
use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.
the class MessageContentProcessor method handleProfileKey.
private void handleProfileKey(@NonNull SignalServiceContent content, @NonNull byte[] messageProfileKeyBytes, @NonNull Recipient senderRecipient) {
RecipientDatabase database = SignalDatabase.recipients();
ProfileKey messageProfileKey = ProfileKeyUtil.profileKeyOrNull(messageProfileKeyBytes);
if (senderRecipient.isSelf()) {
if (!Objects.equals(ProfileKeyUtil.getSelfProfileKey(), messageProfileKey)) {
warn(content.getTimestamp(), "Saw a sync message whose profile key doesn't match our records. Scheduling a storage sync to check.");
StorageSyncHelper.scheduleSyncForDataChange();
}
} else if (messageProfileKey != null) {
if (database.setProfileKey(senderRecipient.getId(), messageProfileKey)) {
log(content.getTimestamp(), "Profile key on message from " + senderRecipient.getId() + " didn't match our local store. It has been updated.");
ApplicationDependencies.getJobManager().add(RetrieveProfileJob.forRecipient(senderRecipient.getId()));
}
} else {
warn(String.valueOf(content.getTimestamp()), "Ignored invalid profile key seen in message");
}
}
use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.
the class MessageContentProcessor method handleSynchronizeMessageRequestResponse.
private void handleSynchronizeMessageRequestResponse(@NonNull MessageRequestResponseMessage response, long envelopeTimestamp) throws BadGroupIdException {
log(envelopeTimestamp, "Synchronize message request response.");
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
ThreadDatabase threadDatabase = SignalDatabase.threads();
Recipient recipient;
if (response.getPerson().isPresent()) {
recipient = Recipient.externalPush(response.getPerson().get());
} else if (response.getGroupId().isPresent()) {
GroupId groupId = GroupId.v1(response.getGroupId().get());
recipient = Recipient.externalPossiblyMigratedGroup(context, groupId);
} else {
warn("Message request response was missing a thread recipient! Skipping.");
return;
}
long threadId = threadDatabase.getOrCreateThreadIdFor(recipient);
switch(response.getType()) {
case ACCEPT:
recipientDatabase.setProfileSharing(recipient.getId(), true);
recipientDatabase.setBlocked(recipient.getId(), false);
break;
case DELETE:
recipientDatabase.setProfileSharing(recipient.getId(), false);
if (threadId > 0)
threadDatabase.deleteConversation(threadId);
break;
case BLOCK:
recipientDatabase.setBlocked(recipient.getId(), true);
recipientDatabase.setProfileSharing(recipient.getId(), false);
break;
case BLOCK_AND_DELETE:
recipientDatabase.setBlocked(recipient.getId(), true);
recipientDatabase.setProfileSharing(recipient.getId(), false);
if (threadId > 0)
threadDatabase.deleteConversation(threadId);
break;
default:
warn("Got an unknown response type! Skipping");
break;
}
}
use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.
the class MessageRequestRepository method acceptMessageRequest.
void acceptMessageRequest(@NonNull LiveRecipient liveRecipient, long threadId, @NonNull Runnable onMessageRequestAccepted, @NonNull GroupChangeErrorCallback error) {
executor.execute(() -> {
if (liveRecipient.get().isPushV2Group()) {
try {
Log.i(TAG, "GV2 accepting invite");
GroupManager.acceptInvite(context, liveRecipient.get().requireGroupId().requireV2());
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
recipientDatabase.setProfileSharing(liveRecipient.getId(), true);
onMessageRequestAccepted.run();
} catch (GroupChangeException | IOException e) {
Log.w(TAG, e);
error.onError(GroupChangeFailureReason.fromException(e));
}
} else {
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
recipientDatabase.setProfileSharing(liveRecipient.getId(), true);
MessageSender.sendProfileKey(context, threadId);
List<MessageDatabase.MarkedMessageInfo> messageIds = SignalDatabase.threads().setEntireThreadRead(threadId);
ApplicationDependencies.getMessageNotifier().updateNotification(context);
MarkReadReceiver.process(context, messageIds);
List<MessageDatabase.MarkedMessageInfo> viewedInfos = SignalDatabase.mms().getViewedIncomingMessages(threadId);
SendViewedReceiptJob.enqueue(threadId, liveRecipient.getId(), viewedInfos);
if (TextSecurePreferences.isMultiDevice(context)) {
ApplicationDependencies.getJobManager().add(MultiDeviceMessageRequestResponseJob.forAccept(liveRecipient.getId()));
}
onMessageRequestAccepted.run();
}
});
}
use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.
the class NotificationChannels method ensureCustomChannelConsistency.
@TargetApi(26)
@WorkerThread
public static synchronized void ensureCustomChannelConsistency(@NonNull Context context) {
if (!supported()) {
return;
}
Log.d(TAG, "ensureCustomChannelConsistency()");
NotificationManager notificationManager = ServiceUtil.getNotificationManager(context);
RecipientDatabase db = SignalDatabase.recipients();
List<Recipient> customRecipients = new ArrayList<>();
Set<String> customChannelIds = new HashSet<>();
try (RecipientDatabase.RecipientReader reader = db.getRecipientsWithNotificationChannels()) {
Recipient recipient;
while ((recipient = reader.getNext()) != null) {
customRecipients.add(recipient);
customChannelIds.add(recipient.getNotificationChannel());
}
}
Set<String> existingChannelIds = Stream.of(notificationManager.getNotificationChannels()).map(NotificationChannel::getId).collect(Collectors.toSet());
for (NotificationChannel existingChannel : notificationManager.getNotificationChannels()) {
if ((existingChannel.getId().startsWith(CONTACT_PREFIX) || existingChannel.getId().startsWith(MESSAGES_PREFIX)) && Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION && existingChannel.getConversationId() != null) {
if (customChannelIds.contains(existingChannel.getId())) {
continue;
}
RecipientId id = ConversationUtil.getRecipientId(existingChannel.getConversationId());
if (id != null) {
Log.i(TAG, "Consistency: Conversation channel created outside of app, update " + id + " to use '" + existingChannel.getId() + "'");
db.setNotificationChannel(id, existingChannel.getId());
} else {
Log.i(TAG, "Consistency: Conversation channel created outside of app with no matching recipient, deleting channel '" + existingChannel.getId() + "'");
notificationManager.deleteNotificationChannel(existingChannel.getId());
}
} else if (existingChannel.getId().startsWith(CONTACT_PREFIX) && !customChannelIds.contains(existingChannel.getId())) {
Log.i(TAG, "Consistency: Deleting channel '" + existingChannel.getId() + "' because the DB has no record of it.");
notificationManager.deleteNotificationChannel(existingChannel.getId());
} else if (existingChannel.getId().startsWith(MESSAGES_PREFIX) && !existingChannel.getId().equals(getMessagesChannel(context))) {
Log.i(TAG, "Consistency: Deleting channel '" + existingChannel.getId() + "' because it's out of date.");
notificationManager.deleteNotificationChannel(existingChannel.getId());
}
}
for (Recipient customRecipient : customRecipients) {
if (!existingChannelIds.contains(customRecipient.getNotificationChannel())) {
Log.i(TAG, "Consistency: Removing custom channel '" + customRecipient.getNotificationChannel() + "' because the system doesn't have it.");
db.setNotificationChannel(customRecipient.getId(), null);
}
}
}
Aggregations