Search in sources :

Example 31 with WorkerThread

use of androidx.annotation.WorkerThread 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 32 with WorkerThread

use of androidx.annotation.WorkerThread 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 33 with WorkerThread

use of androidx.annotation.WorkerThread 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)

Example 34 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class Recipient method externalPush.

/**
 * Returns a fully-populated {@link Recipient} based off of an ACI and phone number, creating one
 * in the database if necessary. We want both piece of information so we're able to associate them
 * both together, depending on which are available.
 *
 * In particular, while we'll eventually get the ACI of a user created via a phone number
 * (through a directory sync), the only way we can store the phone number is by retrieving it from
 * sent messages and whatnot. So we should store it when available.
 *
 * @param highTrust This should only be set to true if the source of the E164-ACI pairing is one
 *                  that can be trusted as accurate (like an envelope).
 */
@WorkerThread
@NonNull
public static Recipient externalPush(@Nullable ServiceId serviceId, @Nullable String e164, boolean highTrust) {
    if (ServiceId.UNKNOWN.equals(serviceId)) {
        throw new AssertionError();
    }
    RecipientDatabase db = SignalDatabase.recipients();
    RecipientId recipientId = db.getAndPossiblyMerge(serviceId, e164, highTrust);
    Recipient resolved = resolved(recipientId);
    if (!resolved.getId().equals(recipientId)) {
        Log.w(TAG, "Resolved " + recipientId + ", but got back a recipient with " + resolved.getId());
    }
    if (highTrust && !resolved.isRegistered() && serviceId != null) {
        Log.w(TAG, "External high-trust push was locally marked unregistered. Marking as registered.");
        db.markRegistered(recipientId, serviceId);
    } else if (highTrust && !resolved.isRegistered()) {
        Log.w(TAG, "External high-trust push was locally marked unregistered, but we don't have an ACI, so we can't do anything.", new Throwable());
    }
    return resolved;
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 35 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class RecipientUtil method unblock.

@WorkerThread
public static void unblock(@NonNull Context context, @NonNull Recipient recipient) {
    if (!isBlockable(recipient)) {
        throw new AssertionError("Recipient is not blockable!");
    }
    SignalDatabase.recipients().setBlocked(recipient.getId(), false);
    SignalDatabase.recipients().setProfileSharing(recipient.getId(), true);
    ApplicationDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob());
    StorageSyncHelper.scheduleSyncForDataChange();
    if (recipient.hasServiceId()) {
        ApplicationDependencies.getJobManager().add(MultiDeviceMessageRequestResponseJob.forAccept(recipient.getId()));
    }
}
Also used : MultiDeviceBlockedUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob) WorkerThread(androidx.annotation.WorkerThread)

Aggregations

WorkerThread (androidx.annotation.WorkerThread)204 NonNull (androidx.annotation.NonNull)77 IOException (java.io.IOException)45 Recipient (org.thoughtcrime.securesms.recipients.Recipient)41 Nullable (androidx.annotation.Nullable)26 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)23 Cursor (android.database.Cursor)22 ArrayList (java.util.ArrayList)22 Context (android.content.Context)20 Uri (android.net.Uri)18 LinkedList (java.util.LinkedList)15 List (java.util.List)15 HashMap (java.util.HashMap)14 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)14 Stream (com.annimon.stream.Stream)13 Log (org.signal.core.util.logging.Log)13 HashSet (java.util.HashSet)12 InputStream (java.io.InputStream)11 Bitmap (android.graphics.Bitmap)10 Collections (java.util.Collections)10