diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/services/NotificationService.java')
-rw-r--r-- | src/main/java/eu/siacs/conversations/services/NotificationService.java | 585 |
1 files changed, 0 insertions, 585 deletions
diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java deleted file mode 100644 index 5ae7e9f1..00000000 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ /dev/null @@ -1,585 +0,0 @@ -package eu.siacs.conversations.services; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.Build; -import android.os.SystemClock; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.NotificationCompat.BigPictureStyle; -import android.support.v4.app.NotificationCompat.Builder; -import android.support.v4.app.TaskStackBuilder; -import android.text.Html; -import android.util.DisplayMetrics; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; - -import de.thedevstack.conversationsplus.ConversationsPlusApplication; -import de.thedevstack.conversationsplus.ConversationsPlusColors; -import de.thedevstack.conversationsplus.ConversationsPlusPreferences; -import de.thedevstack.conversationsplus.utils.ImageUtil; -import de.thedevstack.conversationsplus.utils.MessageUtil; -import de.tzur.conversations.Settings; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.R; -import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.ui.ConversationActivity; -import eu.siacs.conversations.ui.ManageAccountActivity; -import eu.siacs.conversations.utils.GeoHelper; -import eu.siacs.conversations.utils.UIHelper; - -public class NotificationService { - - private final XmppConnectionService mXmppConnectionService; - - private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>(); - - public static final int NOTIFICATION_ID = 0x2342; - public static final int FOREGROUND_NOTIFICATION_ID = 0x8899; - public static final int ERROR_NOTIFICATION_ID = 0x5678; - - private Conversation mOpenConversation; - private boolean mIsInForeground; - private long mLastNotification; - - public NotificationService(final XmppConnectionService service) { - this.mXmppConnectionService = service; - } - - public boolean notify(final Message message) { - return (message.getStatus() == Message.STATUS_RECEIVED) - && !message.isRead() - && ConversationsPlusPreferences.showNotification() - && !message.getConversation().isMuted() - && (message.getConversation().alwaysNotify() || wasHighlightedOrPrivate(message) - ); - } - - public void notifyPebble(final Message message) { - final Intent i = new Intent("com.getpebble.action.SEND_NOTIFICATION"); - - final Conversation conversation = message.getConversation(); - final JSONObject jsonData = new JSONObject(new HashMap<String, String>(2) {{ - put("title", conversation.getName()); - put("body", message.getBody()); - }}); - final String notificationData = new JSONArray().put(jsonData).toString(); - - i.putExtra("messageType", "PEBBLE_ALERT"); - i.putExtra("sender", ConversationsPlusApplication.getName()); - i.putExtra("notificationData", notificationData); - // notify Pebble App - i.setPackage("com.getpebble.android"); - mXmppConnectionService.sendBroadcast(i); - // notify Gadgetbridge - i.setPackage("nodomain.freeyourgadget.gadgetbridge"); - mXmppConnectionService.sendBroadcast(i); - } - - public boolean isQuietHours() { - if (!ConversationsPlusPreferences.enableQuietHours()) { - return false; - } - final long startTime = ConversationsPlusPreferences.quietHoursStart() % Config.MILLISECONDS_IN_DAY; - final long endTime = ConversationsPlusPreferences.quietHoursEnd() % Config.MILLISECONDS_IN_DAY; - final long nowTime = Calendar.getInstance().getTimeInMillis() % Config.MILLISECONDS_IN_DAY; - - if (endTime < startTime) { - return nowTime > startTime || nowTime < endTime; - } else { - return nowTime > startTime && nowTime < endTime; - } - } - - public void pushFromBacklog(final Message message) { - if (notify(message)) { - synchronized (notifications) { - pushToStack(message); - } - } - } - - public void finishBacklog(boolean notify) { - synchronized (notifications) { - mXmppConnectionService.updateUnreadCountBadge(); - updateNotification(notify); - } - } - - private void pushToStack(final Message message) { - final String conversationUuid = message.getConversationUuid(); - if (notifications.containsKey(conversationUuid)) { - notifications.get(conversationUuid).add(message); - } else { - final ArrayList<Message> mList = new ArrayList<>(); - mList.add(message); - notifications.put(conversationUuid, mList); - } - } - - public void push(final Message message) { - if (!notify(message)) { - return; - } - mXmppConnectionService.updateUnreadCountBadge(); - final boolean isScreenOn = mXmppConnectionService.isInteractive(); - if (this.mIsInForeground && isScreenOn && this.mOpenConversation == message.getConversation()) { - return; - } - synchronized (notifications) { - pushToStack(message); - final Account account = message.getConversation().getAccount(); - final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn) - && !account.inGracePeriod() - && !this.inMiniGracePeriod(account); - updateNotification(doNotify); - if (doNotify) { - notifyPebble(message); - } - } - } - - public void clear() { - synchronized (notifications) { - notifications.clear(); - updateNotification(false); - } - } - - public void clear(final Conversation conversation) { - synchronized (notifications) { - notifications.remove(conversation.getUuid()); - updateNotification(false); - } - } - - private void setNotificationColor(final Builder mBuilder) { - mBuilder.setColor(ConversationsPlusColors.notification()); - } - - public void updateNotification(final boolean notify) { - final NotificationManager notificationManager = (NotificationManager) ConversationsPlusApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE); - - final String ringtone = ConversationsPlusPreferences.notificationRingtone(); - final boolean vibrate = ConversationsPlusPreferences.vibrateOnNotification(); - final boolean led = ConversationsPlusPreferences.led(); - - if (notifications.size() == 0) { - notificationManager.cancel(NOTIFICATION_ID); - } else { - if (notify) { - this.markLastNotification(); - } - final Builder mBuilder; - if (notifications.size() == 1) { - mBuilder = buildSingleConversations(notify); - } else { - mBuilder = buildMultipleConversation(); - } - if (notify && !isQuietHours()) { - if (vibrate) { - final int dat = 70; - final long[] pattern = {0, 3 * dat, dat, dat}; - mBuilder.setVibrate(pattern); - } - if (ringtone != null) { - mBuilder.setSound(Uri.parse(ringtone)); - } - } - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setCategory(Notification.CATEGORY_MESSAGE); - } - setNotificationColor(mBuilder); - mBuilder.setDefaults(0); - mBuilder.setSmallIcon(R.drawable.ic_notification); - mBuilder.setDeleteIntent(createDeleteIntent()); - if (led) { - mBuilder.setLights(Settings.LED_COLOR, 2000, 4000); - } - final Notification notification = mBuilder.build(); - notificationManager.notify(NOTIFICATION_ID, notification); - } - } - - private Builder buildMultipleConversation() { - final Builder mBuilder = new NotificationCompat.Builder( - mXmppConnectionService); - final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - style.setBigContentTitle(notifications.size() - + " " - + mXmppConnectionService - .getString(R.string.unread_conversations)); - final StringBuilder names = new StringBuilder(); - Conversation conversation = null; - for (final ArrayList<Message> messages : notifications.values()) { - if (messages.size() > 0) { - conversation = messages.get(0).getConversation(); - final String name = conversation.getName(); - if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) { - int count = messages.size(); - style.addLine(Html.fromHtml("<b>"+name+"</b>: "+mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages,count,count))); - } else { - style.addLine(Html.fromHtml("<b>" + name + "</b>: " - + UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first)); - } - names.append(name); - names.append(", "); - } - } - if (names.length() >= 2) { - names.delete(names.length() - 2, names.length()); - } - mBuilder.setContentTitle(notifications.size() - + " " - + mXmppConnectionService - .getString(R.string.unread_conversations)); - mBuilder.setContentText(names.toString()); - mBuilder.setStyle(style); - if (conversation != null) { - mBuilder.setContentIntent(createContentIntent(conversation)); - } - return mBuilder; - } - - private Builder buildSingleConversations(final boolean notify) { - final Builder mBuilder = new NotificationCompat.Builder( - mXmppConnectionService); - final ArrayList<Message> messages = notifications.values().iterator().next(); - if (messages.size() >= 1) { - final Conversation conversation = messages.get(0).getConversation(); - mBuilder.setLargeIcon(AvatarService.getInstance().get(conversation, getPixel(64))); - mBuilder.setContentTitle(conversation.getName()); - if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) { - int count = messages.size(); - mBuilder.setContentText(mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages,count,count)); - } else { - Message message; - if ((message = getImage(messages)) != null) { - modifyForImage(mBuilder, message, messages, notify); - } else if (conversation.getMode() == Conversation.MODE_MULTI) { - modifyForConference(mBuilder, conversation, messages, notify); - } else { - modifyForTextOnly(mBuilder, messages, notify); - } - if ((message = getFirstDownloadableMessage(messages)) != null) { - mBuilder.addAction( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? - R.drawable.ic_file_download_white_24dp : R.drawable.ic_action_download, - mXmppConnectionService.getResources().getString(R.string.download_x_file, - UIHelper.getFileDescriptionString(mXmppConnectionService, message)), - createDownloadIntent(message) - ); - } - if ((message = getFirstLocationMessage(messages)) != null) { - mBuilder.addAction(R.drawable.ic_room_white_24dp, - mXmppConnectionService.getString(R.string.show_location), - createShowLocationIntent(message)); - } - } - mBuilder.setContentIntent(createContentIntent(conversation)); - } - return mBuilder; - } - - private void modifyForImage(final Builder builder, final Message message, - final ArrayList<Message> messages, final boolean notify) { - try { - final Bitmap bitmap = ImageUtil.getThumbnail(message, getPixel(288), false); - final ArrayList<Message> tmp = new ArrayList<>(); - for (final Message msg : messages) { - if (msg.getType() == Message.TYPE_TEXT - && msg.getTransferable() == null) { - tmp.add(msg); - } - } - final BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(); - bigPictureStyle.bigPicture(bitmap); - if (tmp.size() > 0) { - bigPictureStyle.setSummaryText(getMergedBodies(tmp)); - builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService, tmp.get(0)).first); - } else { - builder.setContentText(mXmppConnectionService.getString( - R.string.received_x_file, - UIHelper.getFileDescriptionString(mXmppConnectionService, message))); - } - builder.setStyle(bigPictureStyle); - } catch (final FileNotFoundException e) { - modifyForTextOnly(builder, messages, notify); - } - } - - private void modifyForTextOnly(final Builder builder, - final ArrayList<Message> messages, final boolean notify) { - builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); - builder.setContentText(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first); - if (notify) { - builder.setTicker(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(messages.size() - 1)).first); - } - } - - private void modifyForConference(Builder builder, Conversation conversation, List<Message> messages, boolean notify) { - final Message first = messages.get(0); - final Message last = messages.get(messages.size() - 1); - final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - style.setBigContentTitle(conversation.getName()); - - for(Message message : messages) { - if (message.hasMeCommand()) { - style.addLine(UIHelper.getMessagePreview(mXmppConnectionService,message).first); - } else { - style.addLine(Html.fromHtml("<b>" + UIHelper.getMessageDisplayName(message) + "</b>: " + UIHelper.getMessagePreview(mXmppConnectionService, message).first)); - } - } - builder.setContentText((first.hasMeCommand() ? "" :UIHelper.getMessageDisplayName(first)+ ": ") +UIHelper.getMessagePreview(mXmppConnectionService, first).first); - builder.setStyle(style); - if (notify) { - builder.setTicker((last.hasMeCommand() ? "" : UIHelper.getMessageDisplayName(last) + ": ") + UIHelper.getMessagePreview(mXmppConnectionService,last).first); - } - } - - private Message getImage(final Iterable<Message> messages) { - for (final Message message : messages) { - if (message.getType() != Message.TYPE_TEXT - && message.getTransferable() == null - && message.getEncryption() != Message.ENCRYPTION_PGP - && message.getFileParams().height > 0) { - return message; - } - } - return null; - } - - private Message getFirstDownloadableMessage(final Iterable<Message> messages) { - for (final Message message : messages) { - if ((message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) && - message.getTransferable() != null) { - return message; - } - } - return null; - } - - private Message getFirstLocationMessage(final Iterable<Message> messages) { - for (final Message message : messages) { - if (GeoHelper.isGeoUri(message.getBody())) { - return message; - } - } - return null; - } - - private CharSequence getMergedBodies(final ArrayList<Message> messages) { - final StringBuilder text = new StringBuilder(); - for (int i = 0; i < messages.size(); ++i) { - text.append(UIHelper.getMessagePreview(mXmppConnectionService, messages.get(i)).first); - if (i != messages.size() - 1) { - text.append("\n"); - } - } - return text.toString(); - } - - private PendingIntent createShowLocationIntent(final Message message) { - Iterable<Intent> intents = GeoHelper.createGeoIntentsFromMessage(message); - for (Intent intent : intents) { - if (intent.resolveActivity(mXmppConnectionService.getPackageManager()) != null) { - return PendingIntent.getActivity(mXmppConnectionService, 18, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - } - return createOpenConversationsIntent(); - } - - private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { - final TaskStackBuilder stackBuilder = TaskStackBuilder - .create(mXmppConnectionService); - stackBuilder.addParentStack(ConversationActivity.class); - - final Intent viewConversationIntent = new Intent(mXmppConnectionService, - ConversationActivity.class); - if (downloadMessageUuid != null) { - viewConversationIntent.setAction(ConversationActivity.ACTION_DOWNLOAD); - } else { - viewConversationIntent.setAction(Intent.ACTION_VIEW); - } - if (conversationUuid != null) { - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversationUuid); - viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); - } - if (downloadMessageUuid != null) { - viewConversationIntent.putExtra(ConversationActivity.MESSAGE, downloadMessageUuid); - } - - stackBuilder.addNextIntent(viewConversationIntent); - - return stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); - } - - private PendingIntent createDownloadIntent(final Message message) { - return createContentIntent(message.getConversationUuid(), message.getUuid()); - } - - private PendingIntent createContentIntent(final Conversation conversation) { - return createContentIntent(conversation.getUuid(), null); - } - - private PendingIntent createDeleteIntent() { - final Intent intent = new Intent(mXmppConnectionService, - XmppConnectionService.class); - intent.setAction(XmppConnectionService.ACTION_CLEAR_NOTIFICATION); - return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); - } - - private PendingIntent createDisableForeground() { - final Intent intent = new Intent(mXmppConnectionService, - XmppConnectionService.class); - intent.setAction(XmppConnectionService.ACTION_DISABLE_FOREGROUND); - return PendingIntent.getService(mXmppConnectionService, 34, intent, 0); - } - - private PendingIntent createTryAgainIntent() { - final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); - intent.setAction(XmppConnectionService.ACTION_TRY_AGAIN); - return PendingIntent.getService(mXmppConnectionService, 45, intent, 0); - } - - private PendingIntent createDisableAccountIntent(final Account account) { - final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); - intent.setAction(XmppConnectionService.ACTION_DISABLE_ACCOUNT); - intent.putExtra("account", account.getJid().toBareJid().toString()); - return PendingIntent.getService(mXmppConnectionService, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - } - - private boolean wasHighlightedOrPrivate(final Message message) { - return MessageUtil.wasHighlightedOrPrivate(message); - } - - public void setOpenConversation(final Conversation conversation) { - this.mOpenConversation = conversation; - } - - public void setIsInForeground(final boolean foreground) { - this.mIsInForeground = foreground; - } - - private int getPixel(final int dp) { - final DisplayMetrics metrics = mXmppConnectionService.getResources() - .getDisplayMetrics(); - return ((int) (dp * metrics.density)); - } - - private void markLastNotification() { - this.mLastNotification = SystemClock.elapsedRealtime(); - } - - private boolean inMiniGracePeriod(final Account account) { - final int miniGrace = account.getStatus() == Account.State.ONLINE ? Config.MINI_GRACE_PERIOD - : Config.MINI_GRACE_PERIOD * 2; - return SystemClock.elapsedRealtime() < (this.mLastNotification + miniGrace); - } - - public Notification createForegroundNotification() { - final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService); - - mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.conversations_foreground_service)); - if (Config.SHOW_CONNECTED_ACCOUNTS) { - List<Account> accounts = mXmppConnectionService.getAccounts(); - int enabled = 0; - int connected = 0; - for (Account account : accounts) { - if (account.isOnlineAndConnected()) { - connected++; - enabled++; - } else if (!account.isOptionSet(Account.OPTION_DISABLED)) { - enabled++; - } - } - mBuilder.setContentText(mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled)); - } else { - mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_open_conversations)); - } - mBuilder.setContentIntent(createOpenConversationsIntent()); - mBuilder.setWhen(0); - mBuilder.setPriority(Config.SHOW_CONNECTED_ACCOUNTS ? NotificationCompat.PRIORITY_DEFAULT : NotificationCompat.PRIORITY_MIN); - final int cancelIcon; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setCategory(Notification.CATEGORY_SERVICE); - cancelIcon = R.drawable.ic_cancel_white_24dp; - } else { - cancelIcon = R.drawable.ic_action_cancel; - } - mBuilder.setSmallIcon(R.drawable.ic_link_white_24dp); - if (Config.SHOW_DISABLE_FOREGROUND) { - mBuilder.addAction(cancelIcon, - mXmppConnectionService.getString(R.string.disable_foreground_service), - createDisableForeground()); - } - return mBuilder.build(); - } - - private PendingIntent createOpenConversationsIntent() { - return PendingIntent.getActivity(mXmppConnectionService, 0, new Intent(mXmppConnectionService, ConversationActivity.class), 0); - } - - public void updateErrorNotification() { - final NotificationManager notificationManager = (NotificationManager) mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE); - final List<Account> errors = new ArrayList<>(); - for (final Account account : mXmppConnectionService.getAccounts()) { - if (account.hasErrorStatus()) { - errors.add(account); - } - } - if (ConversationsPlusPreferences.keepForegroundService()) { - notificationManager.notify(FOREGROUND_NOTIFICATION_ID, createForegroundNotification()); - } - final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService); - if (errors.size() == 0) { - notificationManager.cancel(ERROR_NOTIFICATION_ID); - return; - } else if (errors.size() == 1) { - mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.problem_connecting_to_account)); - mBuilder.setContentText(errors.get(0).getJid().toBareJid().toString()); - } else { - mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.problem_connecting_to_accounts)); - mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_fix)); - } - mBuilder.addAction(R.drawable.ic_autorenew_white_24dp, - mXmppConnectionService.getString(R.string.try_again), - createTryAgainIntent()); - if (errors.size() == 1) { - mBuilder.addAction(R.drawable.ic_block_white_24dp, - mXmppConnectionService.getString(R.string.disable_account), - createDisableAccountIntent(errors.get(0))); - } - mBuilder.setOngoing(true); - //mBuilder.setLights(0xffffffff, 2000, 4000); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp); - } else { - mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); - } - final TaskStackBuilder stackBuilder = TaskStackBuilder.create(mXmppConnectionService); - stackBuilder.addParentStack(ConversationActivity.class); - - final Intent manageAccountsIntent = new Intent(mXmppConnectionService, ManageAccountActivity.class); - stackBuilder.addNextIntent(manageAccountsIntent); - - final PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); - - mBuilder.setContentIntent(resultPendingIntent); - notificationManager.notify(ERROR_NOTIFICATION_ID, mBuilder.build()); - } -} |