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);
}
}
}
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);
}
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);
}
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;
}
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()));
}
}
Aggregations