diff --git a/src/org/thoughtcrime/securesms/notifications/AbstractNotificationBuilder.java b/src/org/thoughtcrime/securesms/notifications/AbstractNotificationBuilder.java deleted file mode 100644 index 9225cf536..000000000 --- a/src/org/thoughtcrime/securesms/notifications/AbstractNotificationBuilder.java +++ /dev/null @@ -1,214 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.content.Context; -import android.graphics.Color; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; -import android.text.SpannableStringBuilder; -import android.text.TextUtils; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.Prefs; -import org.thoughtcrime.securesms.util.Util; - -import java.math.BigInteger; -import java.security.MessageDigest; -import java.util.List; - -abstract class AbstractNotificationBuilder extends NotificationCompat.Builder { - - @SuppressWarnings("unused") - private static final String TAG = AbstractNotificationBuilder.class.getSimpleName(); - - protected Context context; - protected NotificationPrivacyPreference privacy; - private int notificationId; - private Uri ringtone; - private boolean vibrate; - - AbstractNotificationBuilder(Context context, NotificationPrivacyPreference privacy) { - super(context, createMsgNotificationChannel(context)); - - this.context = context; - this.privacy = privacy; - - setLed(); - } - - CharSequence getStyledMessage(@NonNull Recipient recipient, @Nullable CharSequence message) { - SpannableStringBuilder builder = new SpannableStringBuilder(); - builder.append(Util.getBoldedString(recipient.toShortString())); - builder.append(": "); - builder.append(message == null ? "" : message); - - return builder; - } - - // Alarms are not set in the notification or the notification channel but handled separately - // by the MessageNotifier. It allows us to dynamically turn on and off the sounds and as well as - // to change vibration and sounds during runtime - void setAlarms(int systemRingerMode, @Nullable Uri ringtone, Prefs.VibrateState vibrate) { - Uri appDefaultRingtone = Prefs.getNotificationRingtone(context); - boolean appDefaultVibrate = Prefs.isNotificationVibrateEnabled(context); - if (systemRingerMode == AudioManager.RINGER_MODE_NORMAL) { - if (ringtone == null && !TextUtils.isEmpty(appDefaultRingtone.toString())) { - this.ringtone = appDefaultRingtone; - } else if (ringtone != null && !ringtone.toString().isEmpty()) { - this.ringtone = ringtone; - } - } - - this.vibrate = (systemRingerMode != AudioManager.RINGER_MODE_SILENT) && - (vibrate == Prefs.VibrateState.ENABLED || - (vibrate == Prefs.VibrateState.DEFAULT && appDefaultVibrate)); - } - - private void setLed() { - /* - String ledColor = Prefs.getNotificationLedColor(context); - String ledBlinkPattern = Prefs.getNotificationLedPattern(context); - String ledBlinkPatternCustom = Prefs.getNotificationLedPatternCustom(context); - - if (!ledColor.equals("none")) { - String[] blinkPatternArray = parseBlinkPattern(ledBlinkPattern, ledBlinkPatternCustom); - int argb; - try { - argb = Color.parseColor(ledColor); - } - catch (Exception e) { - argb = Color.rgb(0xFF, 0xFF, 0xFF); - } - setLights(argb, - Integer.parseInt(blinkPatternArray[0]), - Integer.parseInt(blinkPatternArray[1])); - } - */ - } - - void setTicker(@NonNull Recipient recipient, @Nullable CharSequence message) { - if (privacy.isDisplayMessage()) { - setTicker(getStyledMessage(recipient, message)); - } else if (privacy.isDisplayContact()) { - setTicker(getStyledMessage(recipient, context.getString(R.string.notify_new_message))); - } else { - setTicker(context.getString(R.string.notify_new_message)); - } - } - - private String[] parseBlinkPattern(String blinkPattern, String blinkPatternCustom) { - if (blinkPattern.equals("custom")) - blinkPattern = blinkPatternCustom; - - return blinkPattern.split(","); - } - - // handle NotificationChannels: - // - since oreo, a NotificationChannel is a MUST - // - NotificationChannels have default values that have a higher precedence as the Notification.Builder setting - // - once created, NotificationChannels cannot be modified programmatically - // - NotificationChannels can be deleted, however, on re-creation it becomes un-deleted with the old settings - // - the idea is that sound and vibrate are handled outside of the scope of the notification channel - - private static String createMsgNotificationChannel(Context context) { - String chBase = "ch_msg3_"; - String chId = chBase + "unsupported"; - - if(notificationChannelsSupported()) { - try { - NotificationManager notificationManager = context.getSystemService(NotificationManager.class); - - // get all values we'll use as settings for the NotificationChannel - String ledColor = Prefs.getNotificationLedColor(context); - - // compute hash from these settings - String hash = ""; - MessageDigest md = MessageDigest.getInstance("SHA-256"); - md.update(ledColor.getBytes()); - hash = String.format("%X", new BigInteger(1, md.digest())).substring(0, 16); - - // get channel name - chId = chBase + hash; - String oldChId = Prefs.getStringPreference(context, "ch_curr_" + chBase, ""); - if (!oldChId.equals(chId)) { - try { - notificationManager.deleteNotificationChannel(oldChId); - } - catch (Exception e) { - // channel not created before - } - Prefs.setStringPreference(context, "ch_curr_" + chBase, chId); - } - - // check if there is already a channel with the given name - List channels = notificationManager.getNotificationChannels(); - boolean channelExists = false; - for (int i = 0; i < channels.size(); i++) { - if (chId.equals(channels.get(i).getId())) { - channelExists = true; - } - } - - // create a channel with the given settings; - // we cannot change the settings, however, this is handled by using different values for chId - if(!channelExists) { - NotificationChannel channel = new NotificationChannel(chId, - "New messages", NotificationManager.IMPORTANCE_HIGH); - channel.setDescription("Informs about new messages."); - - if (!ledColor.equals("none")) { - channel.enableLights(true); - int argb; - try { - argb = Color.parseColor(ledColor); - } - catch (Exception e) { - argb = Color.rgb(0xFF, 0xFF, 0xFF); - } - channel.setLightColor(argb); - } else { - channel.enableLights(false); - } - - channel.setSound(null, null); - channel.enableVibration(false); - - notificationManager.createNotificationChannel(channel); - } - } - catch(Exception e) { - e.printStackTrace(); - } - } - - return chId; - } - - private static boolean notificationChannelsSupported() { - return Build.VERSION.SDK_INT >= 26; - } - - - public void setNotificationId(int notificationId) { - this.notificationId = notificationId; - } - - public int getNotificationId() { - return this.notificationId; - } - - public Uri getRingtone() { - return this.ringtone; - } - - public boolean getVibrate() { - return this.vibrate; - } -} diff --git a/src/org/thoughtcrime/securesms/notifications/MarkAsNoticedAsyncTask.java b/src/org/thoughtcrime/securesms/notifications/MarkAsNoticedAsyncTask.java deleted file mode 100644 index 8f8d3eca6..000000000 --- a/src/org/thoughtcrime/securesms/notifications/MarkAsNoticedAsyncTask.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.os.AsyncTask; - -import org.thoughtcrime.securesms.connect.ApplicationDcContext; - -/** - * This marks the messages the user has acknowledged as noticed. - * @author Angelo Fuchs - */ -public class MarkAsNoticedAsyncTask extends AsyncTask { - private final int[] ids; - private final ApplicationDcContext dcContext; - private final boolean isChat; - - /** - * goes through the given messages or chats and marks them as notified. - * @param ids chat or messages ids to be marked. - * @param dcContext the applications context - * @param isChat true if the ids are chat ids, false to signify message ids. - */ - MarkAsNoticedAsyncTask(int[] ids, ApplicationDcContext dcContext, boolean isChat) { - this.ids = ids; - this.dcContext = dcContext; - this.isChat = isChat; - } - - @Override - protected Void doInBackground(Void... params) { - for (int id : ids) { - if (isChat) - dcContext.marknoticedChat(id); - else - dcContext.marknoticedChat(dcContext.getMsg(id).getChatId()); - } - - return null; - } -} - diff --git a/src/org/thoughtcrime/securesms/notifications/MessageNotifier.java b/src/org/thoughtcrime/securesms/notifications/MessageNotifier.java deleted file mode 100644 index 2bd245a73..000000000 --- a/src/org/thoughtcrime/securesms/notifications/MessageNotifier.java +++ /dev/null @@ -1,412 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.app.NotificationManager; -import android.content.Context; -import android.media.AudioManager; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.media.SoundPool; -import android.net.Uri; -import android.os.Vibrator; -import androidx.annotation.NonNull; -import androidx.core.app.NotificationManagerCompat; -import android.text.TextUtils; -import android.util.Log; - -import com.b44t.messenger.DcChat; -import com.b44t.messenger.DcContext; -import com.b44t.messenger.DcMsg; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.connect.ApplicationDcContext; -import org.thoughtcrime.securesms.connect.DcHelper; -import org.thoughtcrime.securesms.mms.SlideDeck; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.Prefs; -import org.thoughtcrime.securesms.util.ServiceUtil; -import org.thoughtcrime.securesms.util.SpanUtil; - -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.concurrent.TimeUnit; - -import static org.thoughtcrime.securesms.notifications.MessageNotifierCompat.NO_VISIBLE_CHAT_ID; -import static org.thoughtcrime.securesms.notifications.MessageNotifierCompat.SUMMARY_NOTIFICATION_ID; - -abstract class MessageNotifier { - - static final String TAG = org.thoughtcrime.securesms.notifications.MessageNotifierApi23.class.getSimpleName(); - - private static final String NOTIFICATION_GROUP = "messages"; - private static final long MIN_AUDIBLE_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(20); - private static final long STARTUP_SILENCE_DELTA = TimeUnit.MINUTES.toMillis(1); - private static final long INITIAL_STARTUP = System.currentTimeMillis(); - - static volatile int visibleChatId = NO_VISIBLE_CHAT_ID; - static volatile long lastAudibleNotification = -1; - final NotificationState notificationState; - final Context appContext; - final Object lock; - private final SoundPool soundPool; - private final AudioManager audioManager; - private final int soundIn; - private final int soundOut; - private boolean soundInLoaded; - private boolean soundOutLoaded; - - MessageNotifier(Context context) { - appContext = context.getApplicationContext(); - soundPool = new SoundPool(3, AudioManager.STREAM_SYSTEM, 0); - audioManager = ServiceUtil.getAudioManager(appContext); - soundIn = soundPool.load(context, R.raw.sound_in, 1); - soundOut = soundPool.load(context, R.raw.sound_out, 1); - notificationState = new NotificationState(); - lock = new Object(); - - soundPool.setOnLoadCompleteListener((soundPool, sampleId, status) -> { - if (status == 0) { - if (sampleId == soundIn) { - soundInLoaded = true; - } else if (sampleId == soundOut) { - soundOutLoaded = true; - } - } - }); - } - - public void playSendSound() { - if (Prefs.isInChatNotifications(appContext) && soundOutLoaded) { - soundPool.play(soundOut, 1.0f, 1.0f, 1, 0, 1.0f); - } - } - - public void updateVisibleChat(int chatId) { - visibleChatId = chatId; - if (visibleChatId != NO_VISIBLE_CHAT_ID) { - removeNotifications(visibleChatId); - } - } - - void updateNotification(int chatId, int messageId) { - updateNotification(DcHelper.getContext(appContext).getChat(chatId), messageId); - } - - private void updateNotification(DcChat chat, int messageId) { - boolean isVisible = visibleChatId == chat.getId(); - - if (!Prefs.isNotificationsEnabled(appContext) || - Prefs.isChatMuted(chat)) - { - return; - } - - if (isVisible) { - sendInChatNotification(chat); - } else if (visibleChatId != NO_VISIBLE_CHAT_ID) { - //different chat is on top - sendNotifications(chat, messageId, false); - } else { - //app is in background or different Activity is on top - sendNotifications(chat, messageId, true); - } - } - - /** - * On notification privacy preference changed, - * the notification state needs to be updated. - */ - public void onNotificationPrivacyChanged() { - if (!Prefs.isNotificationsEnabled(appContext)) { - return; - } - - clearNotifications(); - ApplicationDcContext dcContext = DcHelper.getContext(appContext); - int[] freshMessages = dcContext.getFreshMsgs(); - for (int message : freshMessages) { - DcMsg record = dcContext.getMsg(message); - updateNotification(dcContext.getChat(record.getChatId()), record.getId()); - } - } - - public void removeNotifications(int[] chatIds) { - List removedItems = new LinkedList<>(); - synchronized (lock) { - for (int id : chatIds) { - removedItems.addAll(notificationState.removeNotificationsForChat(id)); - } - } - cancelNotifications(removedItems); - recreateSummaryNotification(); - } - - public void removeNotifications(int chatId) { - List removedItems; - synchronized (lock) { - removedItems = notificationState.removeNotificationsForChat(chatId); - } - cancelNotifications(removedItems); - recreateSummaryNotification(); - } - - void cancelNotifications(List removedItems) { - NotificationManager notifications = ServiceUtil.getNotificationManager(appContext); - for (NotificationItem item : removedItems) { - notifications.cancel(item.getId()); - } - } - - private void recreateSummaryNotification() { - NotificationManager notifications = ServiceUtil.getNotificationManager(appContext); - notifications.cancel(SUMMARY_NOTIFICATION_ID); - - synchronized (lock) { - if (notificationState.hasMultipleChats()) { - for (Integer id : notificationState.getChats()) { - sendSingleChatNotification(appContext, new NotificationState(notificationState.getNotificationsForChat(id)), false, true); - } - sendMultipleChatNotification(appContext, notificationState, false); - } else { - sendSingleChatNotification(appContext, notificationState, false, false); - } - } - } - - void cancelActiveNotifications() { - NotificationManager notifications = ServiceUtil.getNotificationManager(appContext); - notifications.cancel(SUMMARY_NOTIFICATION_ID); - } - - void sendNotifications(DcChat chat, int messageId, boolean signal) { - ApplicationDcContext dcContext = DcHelper.getContext(appContext); - if (signal = isSignalAllowed(signal)) { - lastAudibleNotification = System.currentTimeMillis(); - } - - if (chat.isDeviceTalk()) { - // currently, we just never notify on device chat. - // esp. on first start, this is annoying. - return; - } - - synchronized (lock) { - addMessageToNotificationState(dcContext, chat, messageId); - if (notificationState.hasMultipleChats()) { - for (int id : notificationState.getChats()) { - sendSingleChatNotification(appContext, new NotificationState(notificationState.getNotificationsForChat(id)), false, true); - } - sendMultipleChatNotification(appContext, notificationState, signal); - } else { - sendSingleChatNotification(appContext, notificationState, signal, false); - } - } - } - - boolean isSignalAllowed(boolean signalRequested) { - long now = System.currentTimeMillis(); - return signalRequested && - (now - INITIAL_STARTUP) > STARTUP_SILENCE_DELTA && - (now - lastAudibleNotification) > MIN_AUDIBLE_PERIOD_MILLIS; - } - - private void clearNotifications() { - synchronized (lock) { - notificationState.reset(); - } - cancelActiveNotifications(); - } - - void sendSingleChatNotification(@NonNull Context context, - @NonNull NotificationState notificationState, - boolean signal, - boolean bundled) - { - AbstractNotificationBuilder notificationBuilder = createSingleChatNotification(context, notificationState, signal, bundled); - if (notificationBuilder != null) - notify(context, notificationBuilder.getNotificationId(), notificationBuilder, signal); - } - - void sendMultipleChatNotification(@NonNull Context context, - @NonNull NotificationState notificationState, - boolean signal) - { - AbstractNotificationBuilder notificationBuilder = createMultipleChatNotification(context, notificationState, signal); - if (notificationBuilder != null) - notify(context, SUMMARY_NOTIFICATION_ID, notificationBuilder, signal); - } - - protected AbstractNotificationBuilder createSingleChatNotification(@NonNull Context context, - @NonNull NotificationState notificationState, - boolean signal, - boolean bundled) { - if (notificationState.getNotifications().isEmpty()) { - if (!bundled) cancelActiveNotifications(); - return null; - } - - SingleRecipientNotificationBuilder builder = new SingleRecipientNotificationBuilder(context, Prefs.getNotificationPrivacy(context)); - List notifications = notificationState.getNotifications(); - NotificationItem firstItem = notifications.get(0); - Recipient recipient = firstItem.getRecipient(); - int chatId = firstItem.getChatId(); - int notificationId = (SUMMARY_NOTIFICATION_ID + (bundled ? chatId : 0)); - - builder.setNotificationId(notificationId); - builder.setChat(firstItem.getRecipient()); - builder.setMessageCount(notificationState.getMessageCount()); - builder.setPrimaryMessageBody(recipient, firstItem.getIndividualRecipient(), - firstItem.getText(""), firstItem.getSlideDeck()); - builder.setContentIntent(firstItem.getPendingIntent(context)); - builder.setGroup(NOTIFICATION_GROUP); - builder.setDeleteIntent(notificationState.getMarkAsReadIntent(context, chatId, notificationId)); - - long timestamp = firstItem.getTimestamp(); - if (timestamp != 0) builder.setWhen(timestamp); - - //builder.addActions(notificationState.getMarkAsReadIntent(context, chatId, notificationId), - // notificationState.getRemoteReplyIntent(context, recipient)); - - ListIterator iterator = notifications.listIterator(notifications.size()); - - while(iterator.hasPrevious()) { - NotificationItem item = iterator.previous(); - builder.addMessageBody(item.getRecipient(), item.getIndividualRecipient(), item.getText()); - } - - if (signal) { - builder.setAlarms(audioManager.getRingerMode(), - notificationState.getRingtone(context), - notificationState.getVibrate(context)); - builder.setTicker(firstItem.getIndividualRecipient(), - firstItem.getText()); - } - - if (!bundled) { - builder.setGroupSummary(true); - } - - return builder; - - - } - - private void playNotificationSound(Uri uri, boolean vibrate) { - if(uri != null) { - Ringtone ringtone = RingtoneManager.getRingtone(appContext, uri); - - if (ringtone != null) { - ringtone.play(); - } - } // else we selected "no sound" - - if (vibrate) { - Vibrator v = (Vibrator) appContext.getSystemService(Context.VIBRATOR_SERVICE); - if (v!=null) { - v.vibrate(100); - v.vibrate(200); - } - } - } - - protected AbstractNotificationBuilder createMultipleChatNotification(@NonNull Context context, - @NonNull NotificationState notificationState, - boolean signal) { - MultipleRecipientNotificationBuilder builder = new MultipleRecipientNotificationBuilder(context, Prefs.getNotificationPrivacy(context)); - List notifications = notificationState.getNotifications(); - NotificationItem firstItem = notifications.get(0); - - builder.setMessageCount(notificationState.getMessageCount(), notificationState.getChatCount()); - builder.setMostRecentSender(firstItem.getIndividualRecipient()); - builder.setGroup(NOTIFICATION_GROUP); - builder.setDeleteIntent(notificationState.getMarkAsReadIntent(context, 0, SUMMARY_NOTIFICATION_ID)); - - long timestamp = firstItem.getTimestamp(); - if (timestamp != 0) builder.setWhen(timestamp); - - builder.addActions(notificationState.getMarkAsReadIntent(context, 0, SUMMARY_NOTIFICATION_ID)); - - ListIterator iterator = notifications.listIterator(notifications.size()); - - while(iterator.hasPrevious()) { - NotificationItem item = iterator.previous(); - builder.addMessageBody(item.getRecipient(), item.getIndividualRecipient(), item.getText()); - } - - if (signal) { - builder.setAlarms(audioManager.getRingerMode(), - notificationState.getRingtone(context), - notificationState.getVibrate(context)); - builder.setTicker(firstItem.getIndividualRecipient(), - firstItem.getText()); - } - - return builder; - } - - private void notify(Context context, int notificationId, AbstractNotificationBuilder notificationBuilder, boolean signal) { - if (signal) { - playNotificationSound(notificationBuilder.getRingtone(), notificationBuilder.getVibrate()); - } - NotificationManagerCompat.from(context).notify(notificationId, notificationBuilder.build()); - } - - private void sendInChatNotification(DcChat chat) { - if (!Prefs.isInChatNotifications(appContext) || - audioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) - { - return; - } - - if(Prefs.isChatMuted(chat)) { - Log.d(TAG, "chat muted"); - return; - } - - if (soundInLoaded) { - soundPool.play(soundIn, 1.0f, 1.0f, 1, 0, 1.0f); - } - } - - void addMessageToNotificationState(ApplicationDcContext dcContext, DcChat chat, int msgId) { - if (Prefs.isChatMuted(chat)) { - return; - } - - DcMsg record = dcContext.getMsg(msgId); - if (record.isInfo()) { - return; - } - - int id = record.getId(); - CharSequence body = record.getDisplayBody(); - DcMsg dcMsg = dcContext.getMsg(msgId); - Recipient chatRecipient = new Recipient(appContext, dcContext.getChat(dcMsg.getChatId()), null); - Recipient individualRecipient = new Recipient(appContext, null, dcContext.getContact(dcMsg.getFromId())); - SlideDeck slideDeck = new SlideDeck(dcContext.context, record); - long timestamp = record.getTimestamp(); - - - if(slideDeck.getSlides().isEmpty()) - slideDeck = null; - - // TODO: if message content should be hidden on screen lock, do it here. - if (record.hasFile() && TextUtils.isEmpty(body)) { - String summaryText = record.getSummarytext(100); - if (summaryText.isEmpty()) { - body = SpanUtil.italic(appContext.getString(R.string.notify_media_message)); - } else { - body = SpanUtil.italic(summaryText); - } - } else if (record.hasFile() && !record.isMediaPending()) { - String message = appContext.getString(R.string.notify_media_message_with_text, body); - int italicLength = message.length() - body.length(); - body = SpanUtil.italic(message, italicLength); - } - - synchronized (lock) { - notificationState.addNotification(new NotificationItem(id, chatRecipient, individualRecipient, chat.getId(), body, timestamp, slideDeck)); - } - } -} - diff --git a/src/org/thoughtcrime/securesms/notifications/MessageNotifierApi23.java b/src/org/thoughtcrime/securesms/notifications/MessageNotifierApi23.java deleted file mode 100644 index 2461392f9..000000000 --- a/src/org/thoughtcrime/securesms/notifications/MessageNotifierApi23.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011 Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.notifications; - -import android.annotation.TargetApi; -import android.app.NotificationManager; -import android.content.Context; -import android.service.notification.StatusBarNotification; -import android.util.Log; - -import org.thoughtcrime.securesms.util.ServiceUtil; - - -/** - * Handles posting system notifications for new messages. - * - */ - -@TargetApi(23) -class MessageNotifierApi23 extends MessageNotifier { - - MessageNotifierApi23(Context context) { - super(context); - } - - void cancelActiveNotifications() { - super.cancelActiveNotifications(); - NotificationManager notifications = ServiceUtil.getNotificationManager(appContext); - try { - - StatusBarNotification[] activeNotifications = notifications.getActiveNotifications(); - for (StatusBarNotification activeNotification : activeNotifications) { - notifications.cancel(activeNotification.getId()); - } - } catch (Throwable e) { - // XXX Appears to be a ROM bug, see #6043 - Log.w(TAG, e); - notifications.cancelAll(); - } - } - - } diff --git a/src/org/thoughtcrime/securesms/notifications/MessageNotifierCompat.java b/src/org/thoughtcrime/securesms/notifications/MessageNotifierCompat.java deleted file mode 100644 index 99e62342a..000000000 --- a/src/org/thoughtcrime/securesms/notifications/MessageNotifierCompat.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.content.Context; -import android.os.Build; - -import org.thoughtcrime.securesms.util.Util; - -public class MessageNotifierCompat { - - public static final int NO_VISIBLE_CHAT_ID = -1; - static final int SUMMARY_NOTIFICATION_ID = 1339; - static final String EXTRA_REMOTE_REPLY = "extra_remote_reply"; - - - private static MessageNotifier instance; - - public static void init(Context context) { - if (instance != null) { - return; - } - - if (Build.VERSION.SDK_INT < 23) { - instance = new MessageNotifierPreApi23(context); - } else { - instance = new MessageNotifierApi23(context); - } - } - - public static void playSendSound() { - instance.playSendSound(); - } - - public static void updateNotification(int chatId, int messageId) { - Util.runOnAnyBackgroundThread(() -> instance.updateNotification(chatId, messageId)); - } - - public static void updateVisibleChat(int chatId) { - Util.runOnAnyBackgroundThread(() -> instance.updateVisibleChat(chatId)); - } - - public static void onNotificationPrivacyChanged() { - Util.runOnAnyBackgroundThread(() -> instance.onNotificationPrivacyChanged()); - } - - static void removeNotifications(int[] chatIds) { - Util.runOnAnyBackgroundThread(() -> instance.removeNotifications(chatIds)); - } - - public static void removeNotifications(int chatId) { - Util.runOnAnyBackgroundThread(() -> instance.removeNotifications(chatId)); - } - - -} diff --git a/src/org/thoughtcrime/securesms/notifications/MessageNotifierPreApi23.java b/src/org/thoughtcrime/securesms/notifications/MessageNotifierPreApi23.java deleted file mode 100644 index 5c622aea4..000000000 --- a/src/org/thoughtcrime/securesms/notifications/MessageNotifierPreApi23.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.content.Context; -import androidx.core.app.NotificationManagerCompat; - -import com.b44t.messenger.DcChat; - -import org.thoughtcrime.securesms.connect.ApplicationDcContext; -import org.thoughtcrime.securesms.connect.DcHelper; - -import java.util.List; - -import static org.thoughtcrime.securesms.notifications.MessageNotifierCompat.SUMMARY_NOTIFICATION_ID; - -class MessageNotifierPreApi23 extends MessageNotifier { - - MessageNotifierPreApi23(Context context) { - super(context); - } - - @Override - public void removeNotifications(int chatId) { - synchronized (lock) { - notificationState.removeNotificationsForChat(chatId); - } - recreateSummaryNotification(); - } - - @Override - public void removeNotifications(int[] chatIds) { - synchronized (lock) { - for (int id : chatIds) { - notificationState.removeNotificationsForChat(id); - } - } - recreateSummaryNotification(); - } - - @Override - void cancelNotifications(List removedItems) { - cancelNotifications(); - } - - @Override - void sendNotifications(DcChat chat, int messageId, boolean signal) { - ApplicationDcContext dcContext = DcHelper.getContext(appContext); - if (signal = isSignalAllowed(signal)) { - lastAudibleNotification = System.currentTimeMillis(); - } - - if (chat.isDeviceTalk()) { - // currently, we just never notify on device chat. - // esp. on first start, this is annoying. - return; - } - - addMessageToNotificationState(dcContext, chat, messageId); - synchronized (lock) { - if (notificationState.hasMultipleChats()) { - sendMultipleChatNotification(appContext, notificationState, signal); - } else { - sendSingleChatNotification(appContext, notificationState, signal, false); - } - } - } - - private void cancelNotifications() { - NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(appContext); - notificationManagerCompat.cancel(SUMMARY_NOTIFICATION_ID); - } - - private void recreateSummaryNotification() { - cancelNotifications(); - synchronized (lock) { - if (notificationState.hasMultipleChats()) { - sendMultipleChatNotification(appContext, notificationState, false); - } else { - sendSingleChatNotification(appContext, notificationState, false, false); - } - } - } -} diff --git a/src/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java b/src/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java deleted file mode 100644 index b3769e878..000000000 --- a/src/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; - -import org.thoughtcrime.securesms.ConversationListActivity; -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.Prefs; -import org.thoughtcrime.securesms.util.Util; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class MultipleRecipientNotificationBuilder extends AbstractNotificationBuilder { - - private final LinkedList messageBodies = new LinkedList<>(); - - private static class MessageBody { - final @Nullable Recipient group; - final @NonNull Recipient sender; - final @NonNull CharSequence message; - - MessageBody(@Nullable Recipient group, @NonNull Recipient sender, @NonNull CharSequence message) { - this.group = group; - this.sender = sender; - this.message = message; - } - } - - MultipleRecipientNotificationBuilder(Context context, NotificationPrivacyPreference privacy) { - super(context, privacy); - - setColor(context.getResources().getColor(R.color.delta_primary)); - setSmallIcon(R.drawable.icon_notification); - setContentTitle(context.getString(R.string.app_name)); - setContentIntent(PendingIntent.getActivity(context, 0, new Intent(context, ConversationListActivity.class), 0)); - setCategory(NotificationCompat.CATEGORY_MESSAGE); - setPriority(Prefs.getNotificationPriority(context)); - setGroupSummary(true); - } - - void setMessageCount(int messageCount, int chatCount) { - setSubText(context.getString(R.string.notify_n_messages_in_m_chats, - messageCount, chatCount)); - setContentInfo(String.valueOf(messageCount)); - setNumber(messageCount); // this also sets badges on android8 and newer - } - - void setMostRecentSender(Recipient recipient) { - if (privacy.isDisplayContact()) { - setContentText(context.getString(R.string.notify_most_recent_from, - recipient.toShortString())); - } - } - - void addActions(PendingIntent markAsReadIntent) { - NotificationCompat.Action markAllAsReadAction = new NotificationCompat.Action(R.drawable.check, - context.getString(R.string.notify_mark_all_read), - markAsReadIntent); - addAction(markAllAsReadAction); - extend(new NotificationCompat.WearableExtender().addAction(markAllAsReadAction)); - } - - void addMessageBody(@Nullable Recipient group, @NonNull Recipient sender, @Nullable CharSequence body) { - messageBodies.add(new MessageBody(group, sender, body)); - - if (privacy.isDisplayContact() && sender.getContactUri() != null) { - addPerson(sender.getContactUri().toString()); - } else if (privacy.isDisplayContact() && group != null && group.getContactUri() != null) { - addPerson(group.getContactUri().toString()); - } - } - - @Override - public Notification build() { - if (privacy.isDisplayMessage() || privacy.isDisplayContact()) { - NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - Map> byGroup = new LinkedHashMap<>(); - for (MessageBody body : messageBodies) { - Recipient key = body.group == null ? body.sender : body.group; - if(byGroup.containsKey(key)) { - LinkedList messagebodies = (LinkedList) byGroup.remove(key); - messagebodies.addFirst(body); - byGroup.put(key, messagebodies); - } else { - byGroup.put(key, new LinkedList<>()); - byGroup.get(key).add(body); - } - } - - if (privacy.isDisplayMessage()) { - LinkedList list = new LinkedList<>(byGroup.keySet()); - Iterator iterator = list.descendingIterator(); - while(iterator.hasNext()) { - Recipient nextGroup = iterator.next(); - String groupName = nextGroup.getName(); - List messages = byGroup.get(nextGroup); - String firstMessageSender = messages.get(0).sender.getName(); - if(groupName != null && groupName.equals(firstMessageSender)) { // individual - for (MessageBody body : messages) { - style.addLine(getStyledMessage(body.sender, body.message)); - } - } else { // group chat - style.addLine(Util.getBoldedString(groupName)); - for (MessageBody body : messages) { - style.addLine("- " + getStyledMessage(body.sender, body.message)); - } - } - } - } else if (privacy.isDisplayContact()) { - LinkedList list = new LinkedList<>(byGroup.keySet()); - Iterator iterator = list.descendingIterator(); - while(iterator.hasNext()) { - Recipient nextGroup = iterator.next(); - String groupName = nextGroup.getName(); - List messages = byGroup.get(nextGroup); - String firstMessageSender = messages.get(0).sender.getName(); - if(groupName != null && groupName.equals(firstMessageSender)) { // individual - for (MessageBody body : messages) { - style.addLine(body.sender.getName()); - } - } else { // group chat - style.addLine(Util.getBoldedString(groupName)); - for (MessageBody body : messages) { - style.addLine("- " + body.sender.getName()); - } - } - } - } - - setStyle(style); - } - - return super.build(); - } -} diff --git a/src/org/thoughtcrime/securesms/notifications/NotificationItem.java b/src/org/thoughtcrime/securesms/notifications/NotificationItem.java deleted file mode 100644 index d3e3e60dd..000000000 --- a/src/org/thoughtcrime/securesms/notifications/NotificationItem.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.TaskStackBuilder; - -import org.thoughtcrime.securesms.ConversationActivity; -import org.thoughtcrime.securesms.mms.SlideDeck; -import org.thoughtcrime.securesms.recipients.Recipient; - -public class NotificationItem { - - private final int id; - private final @NonNull Recipient threadRecipient; - private final @NonNull Recipient individualRecipient; - private final int chatId; - private final @Nullable CharSequence text; - private final long timestamp; - private final @Nullable SlideDeck slideDeck; - - NotificationItem(int id, - @NonNull Recipient threadRecipient, - @NonNull Recipient individualRecipient, - int chatId, @Nullable CharSequence text, long timestamp, - @Nullable SlideDeck slideDeck) - { - this.id = id; - this.threadRecipient = threadRecipient; - this.individualRecipient = individualRecipient; - this.text = text; - this.chatId = chatId; - this.timestamp = timestamp; - this.slideDeck = slideDeck; - } - - public @NonNull Recipient getRecipient() { - return threadRecipient; - } - - public @Nullable CharSequence getText() { - return text; - } - - public @NonNull CharSequence getText(@NonNull CharSequence defaul) { - return (text == null ? defaul : text); - } - - public long getTimestamp() { - return timestamp; - } - - public int getChatId() { - return chatId; - } - - @NonNull Recipient getIndividualRecipient() { - return individualRecipient; - } - - @Deprecated - public int getThreadId() { - return chatId; - } - - @Nullable SlideDeck getSlideDeck() { - return slideDeck; - } - - @NonNull PendingIntent getPendingIntent(Context context) { - Intent intent = new Intent(context, ConversationActivity.class); - - intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, chatId); - intent.setData((Uri.parse("custom://"+System.currentTimeMillis()))); - - return TaskStackBuilder.create(context) - .addNextIntentWithParentStack(intent) - .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); - } - - public int getId() { - return id; - } -} diff --git a/src/org/thoughtcrime/securesms/notifications/NotificationState.java b/src/org/thoughtcrime/securesms/notifications/NotificationState.java deleted file mode 100644 index 2d3f37825..000000000 --- a/src/org/thoughtcrime/securesms/notifications/NotificationState.java +++ /dev/null @@ -1,142 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.Log; - -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.Prefs; -import org.thoughtcrime.securesms.util.Prefs.VibrateState; - -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; - -import static org.thoughtcrime.securesms.notifications.MessageNotifierCompat.SUMMARY_NOTIFICATION_ID; - -public class NotificationState { - - private final LinkedList notifications = new LinkedList<>(); - private final LinkedHashSet chats = new LinkedHashSet<>(); - - private int notificationCount = 0; - - NotificationState() {} - - NotificationState(@NonNull List items) { - for (NotificationItem item : items) { - addNotification(item); - } - } - - public void reset() { - notificationCount = 0; - notifications.clear(); - chats.clear(); - } - - void addNotification(NotificationItem item) { - notifications.addFirst(item); - - if (chats.contains(item.getChatId())) { - chats.remove(item.getChatId()); - } - - chats.add(item.getChatId()); - notificationCount++; - } - - @Nullable Uri getRingtone(Context context) { - if (!notifications.isEmpty()) { - Recipient recipient = notifications.iterator().next().getRecipient(); - if (recipient.getAddress().isDcChat()) { - return Prefs.getChatRingtone(context, recipient.getAddress().getDcChatId()); - } - } - - return null; - } - - VibrateState getVibrate(Context context) { - if (!notifications.isEmpty()) { - Recipient recipient = notifications.iterator().next().getRecipient(); - - if (recipient.getAddress().isDcChat()) { - return Prefs.getChatVibrate(context, recipient.getAddress().getDcChatId()); - } - } - - return VibrateState.DEFAULT; - } - - boolean hasMultipleChats() { - return chats.size() > 1; - } - - public LinkedHashSet getChats() { - return chats; - } - - int getChatCount() { - return chats.size(); - } - - int getMessageCount() { - return notificationCount; - } - - public List getNotifications() { - return notifications; - } - - List getNotificationsForChat(int chatId) { - LinkedList list = new LinkedList<>(); - - for (NotificationItem item : notifications) { - if (item.getChatId() == chatId) list.addFirst(item); - } - - return list; - } - - List removeNotificationsForChat(int chatId) { - LinkedList removedItems = new LinkedList<>(); - chats.remove(chatId); - for (Iterator it = notifications.iterator(); it.hasNext();) { - NotificationItem item = it.next(); - if (item.getChatId() == chatId) { - removedItems.add(item); - it.remove(); - } - } - notificationCount -= removedItems.size(); - return removedItems; - } - - PendingIntent getMarkAsReadIntent(Context context, int chatId, int notificationId) { - int index = 0; - int[] chatArray; - if (notificationId == SUMMARY_NOTIFICATION_ID) { - chatArray = new int[chats.size()]; - for (int chat : chats) { - Log.w("NotificationState", "Added chat: " + chat); - chatArray[index++] = chat; - } - } else { - chatArray = new int[]{chatId}; - } - - Intent intent = new Intent(MarkReadReceiver.CLEAR_ACTION); - intent.setClass(context, MarkReadReceiver.class); - intent.setData((Uri.parse("custom://"+System.currentTimeMillis()))); - //intent.putExtra(MarkReadReceiver.CHAT_IDS_EXTRA, chatArray); - //intent.putExtra(MarkReadReceiver.NOTIFICATION_ID_EXTRA, notificationId); - - return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } -} diff --git a/src/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java b/src/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java deleted file mode 100644 index b06536102..000000000 --- a/src/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.thoughtcrime.securesms.notifications; - -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationCompat.Action; -import androidx.core.app.RemoteInput; -import android.text.SpannableStringBuilder; -import android.util.Log; - -import com.bumptech.glide.load.engine.DiskCacheStrategy; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto; -import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto; -import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto; -import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader; -import org.thoughtcrime.securesms.mms.GlideApp; -import org.thoughtcrime.securesms.mms.Slide; -import org.thoughtcrime.securesms.mms.SlideDeck; -import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.BitmapUtil; -import org.thoughtcrime.securesms.util.Prefs; -import org.thoughtcrime.securesms.util.ThemeUtil; -import org.thoughtcrime.securesms.util.Util; - -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ExecutionException; - -public class SingleRecipientNotificationBuilder extends AbstractNotificationBuilder { - - private static final String TAG = SingleRecipientNotificationBuilder.class.getSimpleName(); - - private final LinkedList messageBodies = new LinkedList<>(); - - private SlideDeck slideDeck; - private CharSequence contentTitle; - private CharSequence contentText; - - SingleRecipientNotificationBuilder(@NonNull Context context, @NonNull NotificationPrivacyPreference privacy) - { - super(context, privacy); - - setSmallIcon(R.drawable.icon_notification); - setColor(context.getResources().getColor(R.color.delta_primary)); - setPriority(Prefs.getNotificationPriority(context)); - setCategory(NotificationCompat.CATEGORY_MESSAGE); - } - - public void setChat(@NonNull Recipient recipient) { - if (privacy.isDisplayContact()) { - setContentTitle(recipient.toShortString()); - - if (recipient.getContactUri() != null) { - addPerson(recipient.getContactUri().toString()); - } - - ContactPhoto contactPhoto = recipient.getContactPhoto(context); - FallbackContactPhoto fallbackContactPhoto = recipient.getFallbackContactPhoto(); - - if (contactPhoto != null) { - try { - setLargeIcon(GlideApp.with(context.getApplicationContext()) - .load(contactPhoto) - .diskCacheStrategy(DiskCacheStrategy.NONE) - .circleCrop() - .submit(context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_width), - context.getResources().getDimensionPixelSize(android.R.dimen.notification_large_icon_height)) - .get()); - } catch (Exception e) { - Log.w(TAG, e); - setLargeIcon(fallbackContactPhoto.asDrawable(context, recipient.getFallbackAvatarColor(context))); - } - } else { - setLargeIcon(fallbackContactPhoto.asDrawable(context, recipient.getFallbackAvatarColor(context))); - } - - } else { - setContentTitle(context.getString(R.string.app_name)); - setLargeIcon(new GeneratedContactPhoto("Unknown").asDrawable(context, ThemeUtil.getDummyContactColor(context))); - } - } - - public void setMessageCount(int messageCount) { - setContentInfo(String.valueOf(messageCount)); - setNumber(messageCount); // this also sets badges on android8 and newer - } - - public void setPrimaryMessageBody(@NonNull Recipient chatRecipients, - @NonNull Recipient individualRecipient, - @NonNull CharSequence message, - @Nullable SlideDeck slideDeck) - { - SpannableStringBuilder stringBuilder = new SpannableStringBuilder(); - - if (privacy.isDisplayContact() && chatRecipients.isGroupRecipient()) { - stringBuilder.append(Util.getBoldedString(individualRecipient.toShortString() + ": ")); - } - - if (privacy.isDisplayMessage()) { - setContentText(stringBuilder.append(message)); - this.slideDeck = slideDeck; - } else { - setContentText(stringBuilder.append(context.getString(R.string.notify_new_message))); - } - } - - void addActions(@NonNull PendingIntent markReadIntent, - @NonNull PendingIntent inNotificationReplyIntent) - { - Action markAsReadAction = new Action(R.drawable.check, - context.getString(R.string.notify_mark_read), - markReadIntent); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - Action replyAction = new Action.Builder(R.drawable.ic_reply_white_36dp, - context.getString(R.string.notify_reply_button), - inNotificationReplyIntent) - .addRemoteInput(new RemoteInput.Builder(MessageNotifierCompat.EXTRA_REMOTE_REPLY) - .setLabel(context.getString(R.string.notify_reply_button)).build()) - .build(); - addAction(replyAction); - } - - Action wearableReplyAction = new Action.Builder(R.drawable.ic_reply, - context.getString(R.string.notify_reply_button), - inNotificationReplyIntent) - .addRemoteInput(new RemoteInput.Builder(MessageNotifierCompat.EXTRA_REMOTE_REPLY) - .setLabel(context.getString(R.string.notify_reply_button)).build()) - .build(); - - addAction(markAsReadAction); - - extend(new NotificationCompat.WearableExtender().addAction(markAsReadAction) - .addAction(wearableReplyAction)); - } - - void addMessageBody(@NonNull Recipient chatRecipient, - @NonNull Recipient individualRecipient, - @Nullable CharSequence messageBody) - { - SpannableStringBuilder stringBuilder = new SpannableStringBuilder(); - - if (privacy.isDisplayContact() && chatRecipient.isGroupRecipient()) { - stringBuilder.append(Util.getBoldedString(individualRecipient.toShortString() + ": ")); - } - - if (privacy.isDisplayMessage()) { - messageBodies.addFirst(stringBuilder.append(messageBody == null ? "" : messageBody)); - } else { - messageBodies.addFirst(stringBuilder.append(context.getString(R.string.notify_new_message))); - } - } - - @Override - public Notification build() { - // the filtering whether or not to display messages and contacts is done in addMessageBody - // and setPrimaryMessageBody, no need to do it here again. - NotificationCompat.Style style; - if (Build.VERSION.SDK_INT < 23) { - style = new NotificationCompat.InboxStyle(); - for (CharSequence messageBody : messageBodies) { - ((NotificationCompat.InboxStyle) style).addLine(messageBody); - } - } else if (messageBodies.size() == 1 && hasBigPictureSlide(slideDeck)) { - style = new NotificationCompat.BigPictureStyle() - .bigPicture(getBigPicture(slideDeck)) - .setSummaryText(getBigText(messageBodies)); - } else { - style = new NotificationCompat.BigTextStyle().bigText(getBigText(messageBodies)); - } - - setStyle(style); - return super.build(); - } - - private void setLargeIcon(@Nullable Drawable drawable) { - if (drawable != null) { - int largeIconTargetSize = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size); - Bitmap recipientPhotoBitmap = BitmapUtil.createFromDrawable(drawable, largeIconTargetSize, largeIconTargetSize); - - if (recipientPhotoBitmap != null) { - setLargeIcon(recipientPhotoBitmap); - } - } - } - - private boolean hasBigPictureSlide(@Nullable SlideDeck slideDeck) { - if (slideDeck == null || Build.VERSION.SDK_INT < 16) { - return false; - } - - Slide thumbnailSlide = slideDeck.getThumbnailSlide(); - - return thumbnailSlide != null && - thumbnailSlide.hasImage() && - thumbnailSlide.getThumbnailUri() != null; - } - - private Bitmap getBigPicture(@NonNull SlideDeck slideDeck) - { - try { - @SuppressWarnings("ConstantConditions") - Uri uri = slideDeck.getThumbnailSlide().getThumbnailUri(); - - return GlideApp.with(context.getApplicationContext()) - .asBitmap() - .load(new DecryptableStreamUriLoader.DecryptableUri(uri)) - .diskCacheStrategy(DiskCacheStrategy.NONE) - .submit(500, 500) - .get(); - } catch (InterruptedException | ExecutionException e) { - Log.w(TAG, e); - return Bitmap.createBitmap(500, 500, Bitmap.Config.RGB_565); - } - } - - @Override - public NotificationCompat.Builder setContentTitle(CharSequence contentTitle) { - this.contentTitle = contentTitle; - return super.setContentTitle(contentTitle); - } - - public NotificationCompat.Builder setContentText(CharSequence contentText) { - this.contentText = contentText; - return super.setContentText(contentText); - } - - private CharSequence getBigText(List messageBodies) { - SpannableStringBuilder content = new SpannableStringBuilder(); - - for (CharSequence message : messageBodies) { - content.append(message); - content.append('\n'); - } - - return content; - } - - -}