diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index ef5ee7288..d14207c9c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -146,6 +146,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr SignalDatabase.init(this, DatabaseSecretProvider.getOrCreateDatabaseSecret(this), AttachmentSecretProvider.getInstance(this).getOrCreateAttachmentSecret()); + SignalDatabase.triggerDatabaseAccess(); }) .addBlocking("logging", () -> { initializeLogging(); @@ -155,7 +156,6 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr .addBlocking("rx-init", this::initializeRx) .addBlocking("event-bus", () -> EventBus.builder().logNoSubscriberMessages(false).installDefaultEventBus()) .addBlocking("app-dependencies", this::initializeAppDependencies) - .addBlocking("notification-channels", () -> NotificationChannels.create(this)) .addBlocking("first-launch", this::initializeFirstEverAppLaunch) .addBlocking("app-migrations", this::initializeApplicationMigrations) .addBlocking("ring-rtc", this::initializeRingRtc) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt index 8d8b69d5e..830377d06 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsFragment.kt @@ -104,7 +104,7 @@ class NotificationsSettingsFragment : DSLSettingsFragment(R.string.preferences__ summary = DSLSettingsText.from(R.string.preferences__change_sound_and_vibration), isEnabled = state.messageNotificationsState.notificationsEnabled, onClick = { - NotificationChannels.openChannelSettings(requireContext(), NotificationChannels.getMessagesChannel(requireContext()), null) + NotificationChannels.getInstance().openChannelSettings(NotificationChannels.getInstance().messagesChannel, null) } ) } else { @@ -301,7 +301,7 @@ class NotificationsSettingsFragment : DSLSettingsFragment(R.string.preferences__ val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) intent.putExtra( Settings.EXTRA_CHANNEL_ID, - NotificationChannels.getMessagesChannel(requireContext()) + NotificationChannels.getInstance().messagesChannel ) intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName) startActivity(intent) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt index 870ec84c8..744a55ca8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/NotificationsSettingsViewModel.kt @@ -16,8 +16,8 @@ class NotificationsSettingsViewModel(private val sharedPreferences: SharedPrefer init { if (NotificationChannels.supported()) { - SignalStore.settings().messageNotificationSound = NotificationChannels.getMessageRingtone(ApplicationDependencies.getApplication()) - SignalStore.settings().isMessageVibrateEnabled = NotificationChannels.getMessageVibrate(ApplicationDependencies.getApplication()) + SignalStore.settings().messageNotificationSound = NotificationChannels.getInstance().messageRingtone + SignalStore.settings().isMessageVibrateEnabled = NotificationChannels.getInstance().messageVibrate } } @@ -33,19 +33,19 @@ class NotificationsSettingsViewModel(private val sharedPreferences: SharedPrefer fun setMessageNotificationsSound(sound: Uri?) { val messageSound = sound ?: Uri.EMPTY SignalStore.settings().messageNotificationSound = messageSound - NotificationChannels.updateMessageRingtone(ApplicationDependencies.getApplication(), messageSound) + NotificationChannels.getInstance().updateMessageRingtone(messageSound) store.update { getState() } } fun setMessageNotificationVibration(enabled: Boolean) { SignalStore.settings().isMessageVibrateEnabled = enabled - NotificationChannels.updateMessageVibrate(ApplicationDependencies.getApplication(), enabled) + NotificationChannels.getInstance().updateMessageVibrate(enabled) store.update { getState() } } fun setMessageNotificationLedColor(color: String) { SignalStore.settings().messageLedColor = color - NotificationChannels.updateMessagesLedColor(ApplicationDependencies.getApplication(), color) + NotificationChannels.getInstance().updateMessagesLedColor(color) store.update { getState() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt index 1e92c2011..c8cde4b06 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/SoundsAndNotificationsSettingsRepository.kt @@ -13,7 +13,7 @@ class SoundsAndNotificationsSettingsRepository(private val context: Context) { fun ensureCustomChannelConsistency(complete: () -> Unit) { SignalExecutors.BOUNDED.execute { if (NotificationChannels.supported()) { - NotificationChannels.ensureCustomChannelConsistency(context) + NotificationChannels.getInstance().ensureCustomChannelConsistency() } complete() } @@ -38,7 +38,7 @@ class SoundsAndNotificationsSettingsRepository(private val context: Context) { if (recipient.notificationChannel != null || !NotificationChannels.supported()) { true } else { - NotificationChannels.updateWithShortcutBasedChannel(context, recipient) + NotificationChannels.getInstance().updateWithShortcutBasedChannel(recipient) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsFragment.kt index 914f7d178..7a6b5e199 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsFragment.kt @@ -91,7 +91,7 @@ class CustomNotificationsSettingsFragment : DSLSettingsFragment(R.string.CustomN title = DSLSettingsText.from(R.string.CustomNotificationsDialogFragment__customize), summary = DSLSettingsText.from(R.string.CustomNotificationsDialogFragment__change_sound_and_vibration), isEnabled = state.controlsEnabled, - onClick = { NotificationChannels.openChannelSettings(requireContext(), state.recipient!!.notificationChannel!!, ConversationUtil.getShortcutId(state.recipient)) } + onClick = { NotificationChannels.getInstance().openChannelSettings(state.recipient!!.notificationChannel!!, ConversationUtil.getShortcutId(state.recipient)) } ) } else { clickPref( diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt index 6d987737d..421cab10b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/sounds/custom/CustomNotificationsSettingsRepository.kt @@ -20,14 +20,14 @@ class CustomNotificationsSettingsRepository(context: Context) { fun ensureCustomChannelConsistency(recipientId: RecipientId, onComplete: () -> Unit) { executor.execute { if (NotificationChannels.supported()) { - NotificationChannels.ensureCustomChannelConsistency(context) + NotificationChannels.getInstance().ensureCustomChannelConsistency() val recipient = Recipient.resolved(recipientId) val database = SignalDatabase.recipients if (recipient.notificationChannel != null) { - val ringtoneUri: Uri? = NotificationChannels.getMessageRingtone(context, recipient) + val ringtoneUri: Uri? = NotificationChannels.getInstance().getMessageRingtone(recipient) database.setMessageRingtone(recipient.id, if (ringtoneUri == Uri.EMPTY) null else ringtoneUri) - database.setMessageVibrate(recipient.id, RecipientDatabase.VibrateState.fromBoolean(NotificationChannels.getMessageVibrate(context, recipient))) + database.setMessageVibrate(recipient.id, RecipientDatabase.VibrateState.fromBoolean(NotificationChannels.getInstance().getMessageVibrate(recipient))) } } @@ -50,7 +50,7 @@ class CustomNotificationsSettingsRepository(context: Context) { val recipient: Recipient = Recipient.resolved(recipientId) SignalDatabase.recipients.setMessageVibrate(recipient.id, vibrateState) - NotificationChannels.updateMessageVibrate(context, recipient, vibrateState) + NotificationChannels.getInstance().updateMessageVibrate(recipient, vibrateState) } } @@ -67,7 +67,7 @@ class CustomNotificationsSettingsRepository(context: Context) { val newValue: Uri? = if (defaultValue == sound) null else sound ?: Uri.EMPTY SignalDatabase.recipients.setMessageRingtone(recipient.id, newValue) - NotificationChannels.updateMessageRingtone(context, recipient, newValue) + NotificationChannels.getInstance().updateMessageRingtone(recipient, newValue) } } @@ -83,7 +83,7 @@ class CustomNotificationsSettingsRepository(context: Context) { @WorkerThread private fun createCustomNotificationChannel(recipientId: RecipientId) { val recipient: Recipient = Recipient.resolved(recipientId) - val channelId = NotificationChannels.createChannelFor(context, recipient) + val channelId = NotificationChannels.getInstance().createChannelFor(recipient) SignalDatabase.recipients.setNotificationChannel(recipient.id, channelId) } @@ -91,6 +91,6 @@ class CustomNotificationsSettingsRepository(context: Context) { private fun deleteCustomNotificationChannel(recipientId: RecipientId) { val recipient: Recipient = Recipient.resolved(recipientId) SignalDatabase.recipients.setNotificationChannel(recipient.id, null) - NotificationChannels.deleteChannelFor(context, recipient) + NotificationChannels.getInstance().deleteChannelFor(recipient) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt index c591afb45..5ff43c193 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscovery.kt @@ -263,7 +263,7 @@ object ContactDiscovery { var recipient: Recipient? = reader.getNext() while (recipient != null) { - NotificationChannels.updateContactChannelName(context, recipient) + NotificationChannels.getInstance().updateContactChannelName(recipient) recipient = reader.getNext() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java index c82024eb2..94b20abb4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationParentFragment.java @@ -705,7 +705,7 @@ public class ConversationParentFragment extends Fragment onRecipientChanged(recipientSnapshot); titleView.setTitle(glideRequests, recipientSnapshot); - NotificationChannels.updateContactChannelName(requireContext(), recipientSnapshot); + NotificationChannels.getInstance().updateContactChannelName(recipientSnapshot); setBlockedUserState(recipientSnapshot, viewModel.getConversationStateSnapshot().getSecurityInfo()); invalidateOptionsMenu(); break; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/EnableCallNotificationSettingsDialog.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/EnableCallNotificationSettingsDialog.java index 389eef3eb..9ac6b113f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/EnableCallNotificationSettingsDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ui/error/EnableCallNotificationSettingsDialog.java @@ -184,7 +184,7 @@ public final class EnableCallNotificationSettingsDialog extends DialogFragment { } private void showNotificationChannelSettings() { - NotificationChannels.openChannelSettings(requireContext(), NotificationChannels.CALLS, null); + NotificationChannels.getInstance().openChannelSettings(NotificationChannels.CALLS, null); } private void showAppSettings() { @@ -194,7 +194,7 @@ public final class EnableCallNotificationSettingsDialog extends DialogFragment { } private static boolean areNotificationsDisabled(@NonNull Context context) { - return !NotificationChannels.areNotificationsEnabled(context); + return !NotificationChannels.getInstance().areNotificationsEnabled(); } private static boolean areCallNotificationsDisabled(Context context) { @@ -202,7 +202,7 @@ public final class EnableCallNotificationSettingsDialog extends DialogFragment { } private static boolean isCallChannelInvalid(Context context) { - return !NotificationChannels.isCallsChannelValid(context); + return !NotificationChannels.getInstance().isCallsChannelValid(); } private static boolean isBackgroundRestricted(Context context) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V149_LegacyMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V149_LegacyMigrations.kt index d9d678163..2fb9e5d22 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V149_LegacyMigrations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V149_LegacyMigrations.kt @@ -371,7 +371,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration { // Note: The column only being checked due to upgrade issues as described in #8184 if (oldVersion < NOTIFICATION_CHANNELS && !SqlUtil.columnExists(db, "recipient_preferences", "notification_channel")) { db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN notification_channel TEXT DEFAULT NULL") - NotificationChannels.create(context) + NotificationChannels.getInstance() db.rawQuery("SELECT recipient_ids, system_display_name, signal_profile_name, notification, vibrate FROM recipient_preferences WHERE notification NOT NULL OR vibrate != 0", null).use { cursor -> while (cursor != null && cursor.moveToNext()) { @@ -382,7 +382,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration { val messageSound: String? = cursor.getString(cursor.getColumnIndexOrThrow("notification")) val messageSoundUri: Uri? = if (messageSound != null) Uri.parse(messageSound) else null val vibrateState: Int = cursor.getInt(cursor.getColumnIndexOrThrow("vibrate")) - var displayName: String? = NotificationChannels.getChannelDisplayNameFor(context, systemName, profileName, null, address) + var displayName: String? = NotificationChannels.getInstance().getChannelDisplayNameFor(systemName, profileName, null, address) val vibrateEnabled: Boolean = if (vibrateState == 0) SignalStore.settings().isMessageVibrateEnabled() else vibrateState == 1 if (GroupId.isEncodedGroup(address)) { db.rawQuery("SELECT title FROM groups WHERE group_id = ?", arrayOf(address)).use { groupCursor -> @@ -394,7 +394,7 @@ object V149_LegacyMigrations : SignalDatabaseMigration { } } } - val channelId: String? = NotificationChannels.createChannelFor(context, "contact_" + address + "_" + System.currentTimeMillis(), (displayName)!!, messageSoundUri, vibrateEnabled, null) + val channelId: String? = NotificationChannels.getInstance().createChannelFor("contact_" + address + "_" + System.currentTimeMillis(), (displayName)!!, messageSoundUri, vibrateEnabled, null) val values = ContentValues(1).apply { put("notification_channel", channelId) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java index 173edeeee..64f2d6540 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java +++ b/app/src/main/java/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceServerTask.java @@ -50,7 +50,7 @@ final class NewDeviceServerTask implements ServerTask { passphrase); SignalDatabase.upgradeRestored(database); - NotificationChannels.restoreContactNotificationChannels(context); + NotificationChannels.getInstance().restoreContactNotificationChannels(); AppInitialization.onPostBackupRestore(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptMessageJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptMessageJob.java index 8418a99df..bcebe9bb1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptMessageJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptMessageJob.java @@ -214,7 +214,7 @@ public final class PushDecryptMessageJob extends BaseJob { private void postMigrationNotification() { NotificationManagerCompat.from(context).notify(NotificationIds.LEGACY_SQLCIPHER_MIGRATION, - new NotificationCompat.Builder(context, NotificationChannels.getMessagesChannel(context)) + new NotificationCompat.Builder(context, NotificationChannels.getInstance().getMessagesChannel()) .setSmallIcon(R.drawable.ic_notification) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_MESSAGE) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java index e1ab73760..324b3d4b3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/SmsReceiveJob.java @@ -195,7 +195,7 @@ public class SmsReceiveJob extends BaseJob { private static Notification buildPreRegistrationNotification(@NonNull Context context, @NonNull IncomingTextMessage message) { Recipient sender = Recipient.resolved(message.getSender()); - return new NotificationCompat.Builder(context, NotificationChannels.getMessagesChannel(context)) + return new NotificationCompat.Builder(context, NotificationChannels.getInstance().getMessagesChannel()) .setStyle(new NotificationCompat.MessagingStyle(new Person.Builder() .setName(sender.getE164().orElse("")) .build()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java index aeb29df81..7c8bc7c8e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/Megaphones.java @@ -227,13 +227,13 @@ public final class Megaphones { .setBody(R.string.NotificationsMegaphone_never_miss_a_message) .setImage(R.drawable.megaphone_notifications_64) .setActionButton(R.string.NotificationsMegaphone_turn_on, (megaphone, controller) -> { - if (Build.VERSION.SDK_INT >= 26 && !NotificationChannels.isMessageChannelEnabled(context)) { + if (Build.VERSION.SDK_INT >= 26 && !NotificationChannels.getInstance().isMessageChannelEnabled()) { Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); - intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationChannels.getMessagesChannel(context)); + intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationChannels.getInstance().getMessagesChannel()); intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); controller.onMegaphoneNavigationRequested(intent); } else if (Build.VERSION.SDK_INT >= 26 && - (!NotificationChannels.areNotificationsEnabled(context) || !NotificationChannels.isMessagesChannelGroupEnabled(context))) + (!NotificationChannels.getInstance().areNotificationsEnabled() || !NotificationChannels.getInstance().isMessagesChannelGroupEnabled())) { Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS); intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName()); @@ -415,9 +415,9 @@ public final class Megaphones { private static boolean shouldShowNotificationsMegaphone(@NonNull Context context) { boolean shouldShow = !SignalStore.settings().isMessageNotificationsEnabled() || - !NotificationChannels.isMessageChannelEnabled(context) || - !NotificationChannels.isMessagesChannelGroupEnabled(context) || - !NotificationChannels.areNotificationsEnabled(context); + !NotificationChannels.getInstance().isMessageChannelEnabled() || + !NotificationChannels.getInstance().isMessagesChannelGroupEnabled() || + !NotificationChannels.getInstance().areNotificationsEnabled(); if (shouldShow) { Locale locale = DynamicLanguageContextWrapper.getUsersSelectedLocale(context); if (!new TranslationDetection(context, locale) diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java index dd1df80e4..0fd5dbcdd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/UserNotificationMigrationJob.java @@ -106,7 +106,7 @@ public class UserNotificationMigrationJob extends MigrationJob { .addNextIntent(newConversationIntent) .getPendingIntent(0, 0); - Notification notification = new NotificationCompat.Builder(context, NotificationChannels.getMessagesChannel(context)) + Notification notification = new NotificationCompat.Builder(context, NotificationChannels.getInstance().getMessagesChannel()) .setSmallIcon(R.drawable.ic_notification) .setContentText(message) .setContentIntent(pendingIntent) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/LocaleChangedReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/LocaleChangedReceiver.java index 6c81f6f5c..3347e31e5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/LocaleChangedReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/LocaleChangedReceiver.java @@ -10,7 +10,7 @@ public class LocaleChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - NotificationChannels.create(context); + NotificationChannels.getInstance().onLocaleChanged(); EmojiSearchIndexDownloadJob.scheduleImmediately(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java index 0e37004e6..0c3a1e7cd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/NotificationChannels.java @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.notifications; import android.annotation.TargetApi; +import android.app.Application; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; @@ -29,6 +30,7 @@ import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.database.RecipientDatabase; import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState; import org.thoughtcrime.securesms.database.SignalDatabase; +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -76,11 +78,29 @@ public class NotificationChannels { public static final String CALL_STATUS = "call_status"; public static final String APP_ALERTS = "app_alerts"; + private static volatile NotificationChannels instance; + + private final Application context; + + public static NotificationChannels getInstance() { + if (instance == null) { + synchronized (NotificationChannels.class) { + if (instance == null) { + instance = new NotificationChannels(ApplicationDependencies.getApplication()); + } + } + } + + return instance; + } + /** * Ensures all of the notification channels are created. No harm in repeat calls. Call is safely * ignored for API < 26. */ - public static synchronized void create(@NonNull Context context) { + private NotificationChannels(@NonNull Application application) { + this.context = application; + if (!supported()) { return; } @@ -93,44 +113,9 @@ public class NotificationChannels { TextSecurePreferences.setNotificationChannelVersion(context, VERSION); } - onCreate(context, notificationManager); + onCreate(notificationManager); - AsyncTask.SERIAL_EXECUTOR.execute(() -> { - ensureCustomChannelConsistency(context); - }); - } - - /** - * Recreates all notification channels for contacts with custom notifications enabled. Should be - * safe to call repeatedly. Needs to be executed on a background thread. - */ - @WorkerThread - public static synchronized void restoreContactNotificationChannels(@NonNull Context context) { - if (!NotificationChannels.supported()) { - return; - } - - RecipientDatabase db = SignalDatabase.recipients(); - - try (RecipientDatabase.RecipientReader reader = db.getRecipientsWithNotificationChannels()) { - Recipient recipient; - while ((recipient = reader.getNext()) != null) { - NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - if (!channelExists(notificationManager.getNotificationChannel(recipient.getNotificationChannel()))) { - String id = createChannelFor(context, recipient); - db.setNotificationChannel(recipient.getId(), id); - } - } - } - - ensureCustomChannelConsistency(context); - } - - /** - * @return The channel ID for the default messages channel. - */ - public static synchronized @NonNull String getMessagesChannel(@NonNull Context context) { - return getMessagesChannelId(TextSecurePreferences.getNotificationMessagesChannelVersion(context)); + AsyncTask.SERIAL_EXECUTOR.execute(this::ensureCustomChannelConsistency); } /** @@ -140,101 +125,10 @@ public class NotificationChannels { return Build.VERSION.SDK_INT >= 26; } - /** - * @return A name suitable to be displayed as the notification channel title. - */ - public static @NonNull String getChannelDisplayNameFor(@NonNull Context context, - @Nullable String systemName, - @Nullable String profileName, - @Nullable String username, - @NonNull String address) - { - if (!TextUtils.isEmpty(systemName)) { - return systemName; - } else if (!TextUtils.isEmpty(profileName)) { - return profileName; - } else if (!TextUtils.isEmpty(username)) { - return username; - } else if (!TextUtils.isEmpty(address)) { - return address; - } else { - return context.getString(R.string.NotificationChannel_missing_display_name); - } - } - - /** - * Creates a channel for the specified recipient. - * @return The channel ID for the newly-created channel. - */ - public static synchronized @Nullable String createChannelFor(@NonNull Context context, @NonNull Recipient recipient) { - if (recipient.getId().isUnknown()) return null; - - VibrateState vibrateState = recipient.getMessageVibrate(); - boolean vibrationEnabled = vibrateState == VibrateState.DEFAULT ? SignalStore.settings().isMessageVibrateEnabled() : vibrateState == VibrateState.ENABLED; - Uri messageRingtone = recipient.getMessageRingtone() != null ? recipient.getMessageRingtone() : getMessageRingtone(context); - String displayName = recipient.getDisplayName(context); - - return createChannelFor(context, generateChannelIdFor(recipient), displayName, messageRingtone, vibrationEnabled, ConversationUtil.getShortcutId(recipient)); - } - - /** - * More verbose version of {@link #createChannelFor(Context, Recipient)}. - */ - public static synchronized @Nullable String createChannelFor(@NonNull Context context, - @NonNull String channelId, - @NonNull String displayName, - @Nullable Uri messageSound, - boolean vibrationEnabled, - @Nullable String shortcutId) - { - if (!supported()) { - return null; - } - - NotificationChannel channel = new NotificationChannel(channelId, displayName, NotificationManager.IMPORTANCE_HIGH); - - setLedPreference(channel, SignalStore.settings().getMessageLedColor()); - channel.setGroup(CATEGORY_MESSAGES); - setVibrationEnabled(channel, vibrationEnabled); - - if (messageSound != null) { - channel.setSound(messageSound, new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) - .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT) - .build()); - } - - if (Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION && shortcutId != null) { - channel.setConversationId(getMessagesChannel(context), shortcutId); - } - - NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - notificationManager.createNotificationChannel(channel); - - return channelId; - } - - /** - * Deletes the channel generated for the provided recipient. Safe to call even if there was never - * a channel made for that recipient. - */ - public static synchronized void deleteChannelFor(@NonNull Context context, @NonNull Recipient recipient) { - if (!supported()) { - return; - } - - NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - String channel = recipient.getNotificationChannel(); - - if (channel != null) { - Log.i(TAG, "Deleting channel"); - notificationManager.deleteNotificationChannel(channel); - } - } - /** * Navigates the user to the system settings for the desired notification channel. */ - public static void openChannelSettings(@NonNull Context context, @NonNull String channelId, @Nullable String conversationId) { + public void openChannelSettings(@NonNull String channelId, @Nullable String conversationId) { if (!supported()) { return; } @@ -253,12 +147,146 @@ public class NotificationChannels { } } + + /** + * @return A name suitable to be displayed as the notification channel title. + */ + public @NonNull String getChannelDisplayNameFor(@Nullable String systemName, + @Nullable String profileName, + @Nullable String username, + @NonNull String address) + { + if (!TextUtils.isEmpty(systemName)) { + return systemName; + } else if (!TextUtils.isEmpty(profileName)) { + return profileName; + } else if (!TextUtils.isEmpty(username)) { + return username; + } else if (!TextUtils.isEmpty(address)) { + return address; + } else { + return context.getString(R.string.NotificationChannel_missing_display_name); + } + } + + /** + * Whether or not notifications for the entire app are enabled. + */ + public synchronized boolean areNotificationsEnabled() { + if (Build.VERSION.SDK_INT >= 24) { + return ServiceUtil.getNotificationManager(context).areNotificationsEnabled(); + } else { + return true; + } + } + + /** + * Recreates all notification channels for contacts with custom notifications enabled. Should be + * safe to call repeatedly. Needs to be executed on a background thread. + */ + @WorkerThread + public synchronized void restoreContactNotificationChannels() { + if (!NotificationChannels.supported()) { + return; + } + + RecipientDatabase db = SignalDatabase.recipients(); + + try (RecipientDatabase.RecipientReader reader = db.getRecipientsWithNotificationChannels()) { + Recipient recipient; + while ((recipient = reader.getNext()) != null) { + NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); + if (!channelExists(notificationManager.getNotificationChannel(recipient.getNotificationChannel()))) { + String id = createChannelFor(recipient); + db.setNotificationChannel(recipient.getId(), id); + } + } + } + + ensureCustomChannelConsistency(); + } + + /** + * @return The channel ID for the default messages channel. + */ + public synchronized @NonNull String getMessagesChannel() { + return getMessagesChannelId(TextSecurePreferences.getNotificationMessagesChannelVersion(context)); + } + + /** + * Creates a channel for the specified recipient. + * @return The channel ID for the newly-created channel. + */ + public synchronized @Nullable String createChannelFor(@NonNull Recipient recipient) { + if (recipient.getId().isUnknown()) return null; + + VibrateState vibrateState = recipient.getMessageVibrate(); + boolean vibrationEnabled = vibrateState == VibrateState.DEFAULT ? SignalStore.settings().isMessageVibrateEnabled() : vibrateState == VibrateState.ENABLED; + Uri messageRingtone = recipient.getMessageRingtone() != null ? recipient.getMessageRingtone() : getMessageRingtone(); + String displayName = recipient.getDisplayName(context); + + return createChannelFor(generateChannelIdFor(recipient), displayName, messageRingtone, vibrationEnabled, ConversationUtil.getShortcutId(recipient)); + } + + /** + * More verbose version of {@link #createChannelFor(Recipient)}. + */ + public synchronized @Nullable String createChannelFor(@NonNull String channelId, + @NonNull String displayName, + @Nullable Uri messageSound, + boolean vibrationEnabled, + @Nullable String shortcutId) + { + if (!supported()) { + return null; + } + + NotificationChannel channel = new NotificationChannel(channelId, displayName, NotificationManager.IMPORTANCE_HIGH); + + setLedPreference(channel, SignalStore.settings().getMessageLedColor()); + channel.setGroup(CATEGORY_MESSAGES); + setVibrationEnabled(channel, vibrationEnabled); + + if (messageSound != null) { + channel.setSound(messageSound, new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT) + .build()); + } + + if (Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION && shortcutId != null) { + channel.setConversationId(getMessagesChannel(), shortcutId); + } + + NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); + notificationManager.createNotificationChannel(channel); + + return channelId; + } + + /** + * Deletes the channel generated for the provided recipient. Safe to call even if there was never + * a channel made for that recipient. + */ + public synchronized void deleteChannelFor(@NonNull Recipient recipient) { + if (!supported()) { + return; + } + + NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); + String channel = recipient.getNotificationChannel(); + + if (channel != null) { + Log.i(TAG, "Deleting channel"); + notificationManager.deleteNotificationChannel(channel); + } + } + /** * Updates the LED color for message notifications and all contact-specific message notification * channels. Performs database operations and should therefore be invoked on a background thread. */ @WorkerThread - public static synchronized void updateMessagesLedColor(@NonNull Context context, @NonNull String color) { + public synchronized void updateMessagesLedColor(@NonNull String color) { if (!supported()) { return; } @@ -266,25 +294,25 @@ public class NotificationChannels { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - updateMessageChannel(context, channel -> setLedPreference(channel, color)); - updateAllRecipientChannelLedColors(context, notificationManager, color); + updateMessageChannel(channel -> setLedPreference(channel, color)); + updateAllRecipientChannelLedColors(notificationManager, color); - ensureCustomChannelConsistency(context); + ensureCustomChannelConsistency(); } /** * @return The message ringtone set for the default message channel. */ - public static synchronized @NonNull Uri getMessageRingtone(@NonNull Context context) { + public synchronized @NonNull Uri getMessageRingtone() { if (!supported()) { return Uri.EMPTY; } - Uri sound = ServiceUtil.getNotificationManager(context).getNotificationChannel(getMessagesChannel(context)).getSound(); + Uri sound = ServiceUtil.getNotificationManager(context).getNotificationChannel(getMessagesChannel()).getSound(); return sound == null ? Uri.EMPTY : sound; } - public static synchronized @Nullable Uri getMessageRingtone(@NonNull Context context, @NonNull Recipient recipient) { + public synchronized @Nullable Uri getMessageRingtone(@NonNull Recipient recipient) { if (!supported() || recipient.resolve().getNotificationChannel() == null) { return null; } @@ -304,13 +332,13 @@ public class NotificationChannels { /** * Update the message ringtone for the default message channel. */ - public static synchronized void updateMessageRingtone(@NonNull Context context, @Nullable Uri uri) { + public synchronized void updateMessageRingtone(@Nullable Uri uri) { if (!supported()) { return; } - Log.i(TAG, "Updating default message ringtone with URI: " + String.valueOf(uri)); + Log.i(TAG, "Updating default message ringtone with URI: " + uri); - updateMessageChannel(context, channel -> { + updateMessageChannel(channel -> { channel.setSound(uri == null ? Settings.System.DEFAULT_NOTIFICATION_URI : uri, getRingtoneAudioAttributes()); }); } @@ -322,11 +350,11 @@ public class NotificationChannels { * This has to update the database, and therefore should be run on a background thread. */ @WorkerThread - public static synchronized void updateMessageRingtone(@NonNull Context context, @NonNull Recipient recipient, @Nullable Uri uri) { + public synchronized void updateMessageRingtone(@NonNull Recipient recipient, @Nullable Uri uri) { if (!supported() || recipient.getNotificationChannel() == null) { return; } - Log.i(TAG, "Updating recipient message ringtone with URI: " + String.valueOf(uri)); + Log.i(TAG, "Updating recipient message ringtone with URI: " + uri); String newChannelId = generateChannelIdFor(recipient); boolean success = updateExistingChannel(ServiceUtil.getNotificationManager(context), @@ -335,27 +363,27 @@ public class NotificationChannels { channel -> channel.setSound(uri == null ? Settings.System.DEFAULT_NOTIFICATION_URI : uri, getRingtoneAudioAttributes())); SignalDatabase.recipients().setNotificationChannel(recipient.getId(), success ? newChannelId : null); - ensureCustomChannelConsistency(context); + ensureCustomChannelConsistency(); } /** * @return The vibrate settings for the default message channel. */ - public static synchronized boolean getMessageVibrate(@NonNull Context context) { + public synchronized boolean getMessageVibrate() { if (!supported()) { return false; } - return ServiceUtil.getNotificationManager(context).getNotificationChannel(getMessagesChannel(context)).shouldVibrate(); + return ServiceUtil.getNotificationManager(context).getNotificationChannel(getMessagesChannel()).shouldVibrate(); } /** * @return The vibrate setting for a specific recipient. If that recipient has no channel, this * will return the setting for the default message channel. */ - public static synchronized boolean getMessageVibrate(@NonNull Context context, @NonNull Recipient recipient) { + public synchronized boolean getMessageVibrate(@NonNull Recipient recipient) { if (!supported()) { - return getMessageVibrate(context); + return getMessageVibrate(); } NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); @@ -363,7 +391,7 @@ public class NotificationChannels { if (!channelExists(channel)) { Log.w(TAG, "Recipient didn't have a channel. Returning message default."); - return getMessageVibrate(context); + return getMessageVibrate(); } return channel.shouldVibrate() && !Arrays.equals(channel.getVibrationPattern(), EMPTY_VIBRATION_PATTERN); @@ -372,13 +400,13 @@ public class NotificationChannels { /** * Sets the vibrate property for the default message channel. */ - public static synchronized void updateMessageVibrate(@NonNull Context context, boolean enabled) { + public synchronized void updateMessageVibrate(boolean enabled) { if (!supported()) { return; } Log.i(TAG, "Updating default vibrate with value: " + enabled); - updateMessageChannel(context, channel -> setVibrationEnabled(channel, enabled)); + updateMessageChannel(channel -> setVibrationEnabled(channel, enabled)); } /** @@ -388,13 +416,13 @@ public class NotificationChannels { * This has to update the database and should therefore be run on a background thread. */ @WorkerThread - public static synchronized void updateMessageVibrate(@NonNull Context context, @NonNull Recipient recipient, VibrateState vibrateState) { + public synchronized void updateMessageVibrate(@NonNull Recipient recipient, VibrateState vibrateState) { if (!supported() || recipient.getNotificationChannel() == null) { return ; } Log.i(TAG, "Updating recipient vibrate with value: " + vibrateState); - boolean enabled = vibrateState == VibrateState.DEFAULT ? getMessageVibrate(context) : vibrateState == VibrateState.ENABLED; + boolean enabled = vibrateState == VibrateState.DEFAULT ? getMessageVibrate() : vibrateState == VibrateState.ENABLED; String newChannelId = generateChannelIdFor(recipient); boolean success = updateExistingChannel(ServiceUtil.getNotificationManager(context), @@ -403,7 +431,7 @@ public class NotificationChannels { channel -> setVibrationEnabled(channel, enabled)); SignalDatabase.recipients().setNotificationChannel(recipient.getId(), success ? newChannelId : null); - ensureCustomChannelConsistency(context); + ensureCustomChannelConsistency(); } /** @@ -415,7 +443,7 @@ public class NotificationChannels { * Likewise, setting the pattern to any non-zero length array will set enable vibration flag to true. */ @TargetApi(26) - private static void setVibrationEnabled(@NonNull NotificationChannel channel, boolean enabled) { + private void setVibrationEnabled(@NonNull NotificationChannel channel, boolean enabled) { if (enabled) { channel.setVibrationPattern(null); channel.enableVibration(true); @@ -431,16 +459,16 @@ public class NotificationChannels { * * This could also return true if the specific channnel is enabled, but notifications *overall* * are disabled, or the messages category is disabled. Check - * {@link #areNotificationsEnabled(Context)} and {@link #isMessagesChannelGroupEnabled(Context)} + * {@link #areNotificationsEnabled()} and {@link #isMessagesChannelGroupEnabled()} * to be safe. */ - public static synchronized boolean isMessageChannelEnabled(@NonNull Context context) { + public synchronized boolean isMessageChannelEnabled() { if (!supported()) { return true; } NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); - NotificationChannel channel = notificationManager.getNotificationChannel(getMessagesChannel(context)); + NotificationChannel channel = notificationManager.getNotificationChannel(getMessagesChannel()); return channel != null && channel.getImportance() != NotificationManager.IMPORTANCE_NONE; } @@ -448,9 +476,9 @@ public class NotificationChannels { /** * Whether or not the notification category for messages is enabled. Note that even if it is, * a user could have blocked the specific channel, or notifications overall, and it'd still be - * true. See {@link #isMessageChannelEnabled(Context)} and {@link #areNotificationsEnabled(Context)}. + * true. See {@link #isMessageChannelEnabled()} and {@link #areNotificationsEnabled()}. */ - public static synchronized boolean isMessagesChannelGroupEnabled(@NonNull Context context) { + public synchronized boolean isMessagesChannelGroupEnabled() { if (Build.VERSION.SDK_INT < 28) { return true; } @@ -461,7 +489,7 @@ public class NotificationChannels { return group != null && !group.isBlocked(); } - public static boolean isCallsChannelValid(@NonNull Context context) { + public synchronized boolean isCallsChannelValid() { if (!supported()) { return true; } @@ -472,17 +500,6 @@ public class NotificationChannels { return channel != null && channel.getImportance() == NotificationManager.IMPORTANCE_HIGH; } - /** - * Whether or not notifications for the entire app are enabled. - */ - public static synchronized boolean areNotificationsEnabled(@NonNull Context context) { - if (Build.VERSION.SDK_INT >= 24) { - return ServiceUtil.getNotificationManager(context).areNotificationsEnabled(); - } else { - return true; - } - } - /** * Attempt to update a recipient with shortcut based notification channel if the system made one for us and we don't * have a channel set yet. @@ -490,7 +507,7 @@ public class NotificationChannels { * @return true if a shortcut based notification channel was found and then associated with the recipient, false otherwise */ @WorkerThread - public static boolean updateWithShortcutBasedChannel(@NonNull Context context, @NonNull Recipient recipient) { + public boolean updateWithShortcutBasedChannel(@NonNull Recipient recipient) { if (Build.VERSION.SDK_INT >= CONVERSATION_SUPPORT_VERSION && TextUtils.isEmpty(recipient.getNotificationChannel())) { String shortcutId = ConversationUtil.getShortcutId(recipient); @@ -513,7 +530,7 @@ public class NotificationChannels { * Updates the name of an existing channel to match the recipient's current name. Will have no * effect if the recipient doesn't have an existing valid channel. */ - public static synchronized void updateContactChannelName(@NonNull Context context, @NonNull Recipient recipient) { + public synchronized void updateContactChannelName(@NonNull Recipient recipient) { if (!supported() || recipient.getNotificationChannel() == null) { return; } @@ -535,7 +552,7 @@ public class NotificationChannels { @TargetApi(26) @WorkerThread - public static synchronized void ensureCustomChannelConsistency(@NonNull Context context) { + public synchronized void ensureCustomChannelConsistency() { if (!supported()) { return; } @@ -576,7 +593,7 @@ public class NotificationChannels { } 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))) { + } else if (existingChannel.getId().startsWith(MESSAGES_PREFIX) && !existingChannel.getId().equals(getMessagesChannel())) { Log.i(TAG, "Consistency: Deleting channel '" + existingChannel.getId() + "' because it's out of date."); notificationManager.deleteNotificationChannel(existingChannel.getId()); } @@ -590,12 +607,19 @@ public class NotificationChannels { } } + public synchronized void onLocaleChanged() { + if (!supported()) { + return; + } + onCreate(ServiceUtil.getNotificationManager(context)); + } + @TargetApi(26) - private static void onCreate(@NonNull Context context, @NonNull NotificationManager notificationManager) { + private void onCreate(@NonNull NotificationManager notificationManager) { NotificationChannelGroup messagesGroup = new NotificationChannelGroup(CATEGORY_MESSAGES, context.getResources().getString(R.string.NotificationChannel_group_chats)); notificationManager.createNotificationChannelGroup(messagesGroup); - NotificationChannel messages = new NotificationChannel(getMessagesChannel(context), context.getString(R.string.NotificationChannel_channel_messages), NotificationManager.IMPORTANCE_HIGH); + NotificationChannel messages = new NotificationChannel(getMessagesChannel(), context.getString(R.string.NotificationChannel_channel_messages), NotificationManager.IMPORTANCE_HIGH); NotificationChannel calls = new NotificationChannel(CALLS, context.getString(R.string.NotificationChannel_calls), NotificationManager.IMPORTANCE_HIGH); NotificationChannel failures = new NotificationChannel(FAILURES, context.getString(R.string.NotificationChannel_failures), NotificationManager.IMPORTANCE_HIGH); NotificationChannel backups = new NotificationChannel(BACKUPS, context.getString(R.string.NotificationChannel_backups), NotificationManager.IMPORTANCE_LOW); @@ -708,7 +732,7 @@ public class NotificationChannels { @WorkerThread @TargetApi(26) - private static void updateAllRecipientChannelLedColors(@NonNull Context context, @NonNull NotificationManager notificationManager, @NonNull String color) { + private void updateAllRecipientChannelLedColors(@NonNull NotificationManager notificationManager, @NonNull String color) { RecipientDatabase database = SignalDatabase.recipients(); try (RecipientDatabase.RecipientReader recipients = database.getRecipientsWithNotificationChannels()) { @@ -723,11 +747,11 @@ public class NotificationChannels { } } - ensureCustomChannelConsistency(context); + ensureCustomChannelConsistency(); } @TargetApi(26) - private static void updateMessageChannel(@NonNull Context context, @NonNull ChannelUpdater updater) { + private void updateMessageChannel(@NonNull ChannelUpdater updater) { NotificationManager notificationManager = ServiceUtil.getNotificationManager(context); int existingVersion = TextSecurePreferences.getNotificationMessagesChannelVersion(context); int newVersion = existingVersion + 1; @@ -736,7 +760,7 @@ public class NotificationChannels { if (updateExistingChannel(notificationManager, getMessagesChannelId(existingVersion), getMessagesChannelId(newVersion), updater)) { TextSecurePreferences.setNotificationMessagesChannelVersion(context, newVersion); } else { - onCreate(context, notificationManager); + onCreate(notificationManager); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt index 1b87a535d..d82f613fe 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/DefaultMessageNotifier.kt @@ -120,7 +120,7 @@ class DefaultMessageNotifier(context: Application) : MessageNotifier { reminderCount: Int, defaultBubbleState: BubbleState ) { - NotificationChannels.ensureCustomChannelConsistency(context) + NotificationChannels.getInstance().ensureCustomChannelConsistency() val currentLockStatus: Boolean = KeyCachingService.isLocked(context) val currentPrivacyPreference: NotificationPrivacyPreference = SignalStore.settings().messageNotificationsPrivacy diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt index e81e23922..e967d1832 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationBuilder.kt @@ -186,7 +186,7 @@ sealed class NotificationBuilder(protected val context: Context) { * Notification builder using solely androidx/compat libraries. */ private class NotificationBuilderCompat(context: Context) : NotificationBuilder(context) { - val builder: NotificationCompat.Builder = NotificationCompat.Builder(context, NotificationChannels.getMessagesChannel(context)) + val builder: NotificationCompat.Builder = NotificationCompat.Builder(context, NotificationChannels.getInstance().messagesChannel) override fun addActions(replyMethod: ReplyMethod, conversation: NotificationConversation) { val extender: NotificationCompat.WearableExtender = NotificationCompat.WearableExtender() diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationConversation.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationConversation.kt index bea9fc342..71be630cc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationConversation.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationConversation.kt @@ -103,7 +103,7 @@ data class NotificationConversation( return if (isOnlyContactJoinedEvent) { NotificationChannels.JOIN_EVENTS } else { - recipient.notificationChannel ?: NotificationChannels.getMessagesChannel(context) + recipient.notificationChannel ?: NotificationChannels.getInstance().messagesChannel } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt index 6babe5511..db29cc695 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/v2/NotificationFactory.kt @@ -237,7 +237,7 @@ object NotificationFactory { setCategory(NotificationCompat.CATEGORY_MESSAGE) setGroup(DefaultMessageNotifier.NOTIFICATION_GROUP) setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN) - setChannelId(NotificationChannels.getMessagesChannel(context)) + setChannelId(NotificationChannels.getInstance().messagesChannel) setContentTitle(context.getString(R.string.app_name)) setContentIntent(NotificationPendingIntentHelper.getActivity(context, 0, MainActivity.clearTop(context), PendingIntentFlags.mutable())) setGroupSummary(true) @@ -269,7 +269,7 @@ object NotificationFactory { } val uri: Uri = if (NotificationChannels.supported()) { - NotificationChannels.getMessageRingtone(context, recipient) ?: NotificationChannels.getMessageRingtone(context) + NotificationChannels.getInstance().getMessageRingtone(recipient) ?: NotificationChannels.getInstance().messageRingtone } else { recipient.messageRingtone ?: SignalStore.settings().messageNotificationSound } @@ -402,7 +402,7 @@ object NotificationFactory { if (threadRecipient != null) { SignalExecutors.BOUNDED.execute { SignalDatabase.recipients.setMessageRingtone(threadRecipient.id, null) - NotificationChannels.updateMessageRingtone(context, threadRecipient, null) + NotificationChannels.getInstance().updateMessageRingtone(threadRecipient, null) } } } catch (runtimeException: RuntimeException) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java index 2187c499a..493741f58 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragment.java @@ -292,7 +292,7 @@ public final class RestoreBackupFragment extends LoggingFragment { passphrase); SignalDatabase.upgradeRestored(database); - NotificationChannels.restoreContactNotificationChannels(context); + NotificationChannels.getInstance().restoreContactNotificationChannels(); enableBackups(context); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java index f5157392f..ba1240bd8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/ConversationUtil.java @@ -53,7 +53,7 @@ public final class ConversationUtil { public static @NonNull String getChannelId(@NonNull Context context, @NonNull Recipient recipient) { Recipient resolved = recipient.resolve(); - return resolved.getNotificationChannel() != null ? resolved.getNotificationChannel() : NotificationChannels.getMessagesChannel(context); + return resolved.getNotificationChannel() != null ? resolved.getNotificationChannel() : NotificationChannels.getInstance().getMessagesChannel(); } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java index 2aed32a55..a3f24fd1c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java @@ -288,7 +288,7 @@ public class TextSecurePreferences { public static void onPostBackupRestore(@NonNull Context context) { if (NotificationChannels.supported()) { - NotificationChannels.updateMessageVibrate(context, SignalStore.settings().isMessageVibrateEnabled()); + NotificationChannels.getInstance().updateMessageVibrate(SignalStore.settings().isMessageVibrateEnabled()); } }