Search in sources :

Example 1 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.

the class MultiDeviceBlockedUpdateJob method onRun.

@Override
public void onRun(MasterSecret masterSecret) throws IOException, UntrustedIdentityException {
    RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context);
    BlockedReader reader = database.readerForBlocked(database.getBlocked());
    List<String> blocked = new LinkedList<>();
    Recipient recipient;
    while ((recipient = reader.getNext()) != null) {
        if (!recipient.isGroupRecipient()) {
            blocked.add(recipient.getAddress().serialize());
        }
    }
    messageSender.sendMessage(SignalServiceSyncMessage.forBlocked(new BlockedListMessage(blocked)));
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) Recipient(org.thoughtcrime.securesms.recipients.Recipient) BlockedReader(org.thoughtcrime.securesms.database.RecipientDatabase.BlockedReader) BlockedListMessage(org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage) LinkedList(java.util.LinkedList)

Example 2 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.

the class RetrieveProfileAvatarJob method onRun.

@Override
public void onRun() throws IOException {
    RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context);
    byte[] profileKey = recipient.resolve().getProfileKey();
    if (profileKey == null) {
        Log.w(TAG, "Recipient profile key is gone!");
        return;
    }
    if (Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) {
        Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar);
        return;
    }
    if (TextUtils.isEmpty(profileAvatar)) {
        Log.w(TAG, "Removing profile avatar for: " + recipient.getAddress().serialize());
        AvatarHelper.delete(context, recipient.getAddress());
        database.setProfileAvatar(recipient, profileAvatar);
        return;
    }
    File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
    try {
        InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, MAX_PROFILE_SIZE_BYTES);
        File decryptDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
        Util.copy(avatarStream, new FileOutputStream(decryptDestination));
        decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.getAddress()));
    } finally {
        if (downloadDestination != null)
            downloadDestination.delete();
    }
    database.setProfileAvatar(recipient, profileAvatar);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) InputStream(java.io.InputStream) FileOutputStream(java.io.FileOutputStream) File(java.io.File)

Example 3 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by WhisperSystems.

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);
        }
    }
}
Also used : NotificationChannel(android.app.NotificationChannel) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) NotificationManager(android.app.NotificationManager) ArrayList(java.util.ArrayList) Recipient(org.thoughtcrime.securesms.recipients.Recipient) HashSet(java.util.HashSet) WorkerThread(androidx.annotation.WorkerThread) TargetApi(android.annotation.TargetApi)

Example 4 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by WhisperSystems.

the class NotificationChannels method updateAllRecipientChannelLedColors.

@WorkerThread
@TargetApi(26)
private static void updateAllRecipientChannelLedColors(@NonNull Context context, @NonNull NotificationManager notificationManager, @NonNull String color) {
    RecipientDatabase database = SignalDatabase.recipients();
    try (RecipientDatabase.RecipientReader recipients = database.getRecipientsWithNotificationChannels()) {
        Recipient recipient;
        while ((recipient = recipients.getNext()) != null) {
            assert recipient.getNotificationChannel() != null;
            String newChannelId = generateChannelIdFor(recipient);
            boolean success = updateExistingChannel(notificationManager, recipient.getNotificationChannel(), newChannelId, channel -> setLedPreference(channel, color));
            database.setNotificationChannel(recipient.getId(), success ? newChannelId : null);
        }
    }
    ensureCustomChannelConsistency(context);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) Recipient(org.thoughtcrime.securesms.recipients.Recipient) WorkerThread(androidx.annotation.WorkerThread) TargetApi(android.annotation.TargetApi)

Example 5 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by WhisperSystems.

the class Recipient method externalContact.

/**
 * A safety wrapper around {@link #external(Context, String)} for when you know you're using an
 * identifier for a system contact, and therefore always want to prevent interpreting it as a
 * UUID. This will crash if given a UUID.
 *
 * (This may seem strange, but apparently some devices are returning valid UUIDs for contacts)
 */
@WorkerThread
@NonNull
public static Recipient externalContact(@NonNull Context context, @NonNull String identifier) {
    RecipientDatabase db = SignalDatabase.recipients();
    RecipientId id = null;
    if (UuidUtil.isUuid(identifier)) {
        throw new AssertionError("UUIDs are not valid system contact identifiers!");
    } else if (NumberUtil.isValidEmail(identifier)) {
        id = db.getOrInsertFromEmail(identifier);
    } else {
        id = db.getOrInsertFromE164(identifier);
    }
    return Recipient.resolved(id);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Aggregations

RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)39 Recipient (org.thoughtcrime.securesms.recipients.Recipient)17 WorkerThread (androidx.annotation.WorkerThread)15 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)10 NonNull (androidx.annotation.NonNull)9 IOException (java.io.IOException)7 Nullable (androidx.annotation.Nullable)5 ArrayList (java.util.ArrayList)5 Log (org.signal.core.util.logging.Log)5 SignalDatabase (org.thoughtcrime.securesms.database.SignalDatabase)5 ACI (org.whispersystems.signalservice.api.push.ACI)5 Context (android.content.Context)4 Stream (com.annimon.stream.Stream)4 Collections (java.util.Collections)4 List (java.util.List)4 TimeUnit (java.util.concurrent.TimeUnit)4 ProfileKey (org.signal.zkgroup.profiles.ProfileKey)4 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)4 Optional (org.whispersystems.libsignal.util.guava.Optional)4 Collectors (com.annimon.stream.Collectors)3