notify only after image has been received over http. introduced mini grace for catching up with SM or offline messages

iNPUTmice created

Change summary

src/eu/siacs/conversations/Config.java                         |  1 
src/eu/siacs/conversations/entities/Message.java               | 15 -
src/eu/siacs/conversations/http/HttpConnection.java            |  9 
src/eu/siacs/conversations/parser/MessageParser.java           |  1 
src/eu/siacs/conversations/services/NotificationService.java   | 59 +++
src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java | 12 
6 files changed, 64 insertions(+), 33 deletions(-)

Detailed changes

src/eu/siacs/conversations/Config.java 🔗

@@ -11,6 +11,7 @@ public final class Config {
 	public static final int PING_TIMEOUT = 10;
 	public static final int CONNECT_TIMEOUT = 90;
 	public static final int CARBON_GRACE_PERIOD = 60;
+	public static final int MINI_GRACE_PERIOD = 750;
 
 	public static final int AVATAR_SIZE = 192;
 	public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP;

src/eu/siacs/conversations/entities/Message.java 🔗

@@ -5,9 +5,7 @@ import java.net.URL;
 import java.util.Arrays;
 
 import eu.siacs.conversations.Config;
-import eu.siacs.conversations.R;
 import android.content.ContentValues;
-import android.content.Context;
 import android.database.Cursor;
 
 public class Message extends AbstractEntity {
@@ -145,19 +143,6 @@ public class Message extends AbstractEntity {
 		return body;
 	}
 
-	public String getReadableBody(Context context) {
-		if (encryption == ENCRYPTION_PGP) {
-			return context.getText(R.string.encrypted_message_received)
-					.toString();
-		} else if (encryption == ENCRYPTION_DECRYPTION_FAILED) {
-			return context.getText(R.string.decryption_failed).toString();
-		} else if (type == TYPE_IMAGE) {
-			return context.getText(R.string.image_file).toString();
-		} else {
-			return body.trim();
-		}
-	}
-
 	public long getTimeSent() {
 		return timeSent;
 	}

src/eu/siacs/conversations/http/HttpConnection.java 🔗

@@ -36,6 +36,7 @@ public class HttpConnection implements Downloadable {
 	private Message message;
 	private DownloadableFile file;
 	private int mStatus = Downloadable.STATUS_UNKNOWN;
+	private boolean acceptedAutomatically = false;
 
 	public HttpConnection(HttpConnectionManager manager) {
 		this.mHttpConnectionManager = manager;
@@ -99,6 +100,9 @@ public class HttpConnection implements Downloadable {
 		message.setDownloadable(null);
 		mHttpConnectionManager.finishConnection(this);
 		mXmppConnectionService.updateConversationUi();
+		if (acceptedAutomatically) {
+			mXmppConnectionService.getNotificationService().push(message);
+		}
 	}
 
 	private void changeStatus(int status) {
@@ -151,6 +155,8 @@ public class HttpConnection implements Downloadable {
 				size = retrieveFileSize();
 			} catch (SSLHandshakeException e) {
 				changeStatus(STATUS_OFFER_CHECK_FILESIZE);
+				HttpConnection.this.acceptedAutomatically = false;
+				HttpConnection.this.mXmppConnectionService.getNotificationService().push(message);
 				return;
 			} catch (IOException e) {
 				cancel();
@@ -158,9 +164,12 @@ public class HttpConnection implements Downloadable {
 			}
 			file.setExpectedSize(size);
 			if (size <= mHttpConnectionManager.getAutoAcceptFileSize()) {
+				HttpConnection.this.acceptedAutomatically = true;
 				new Thread(new FileDownloader(interactive)).start();
 			} else {
 				changeStatus(STATUS_OFFER);
+				HttpConnection.this.acceptedAutomatically = false;
+				HttpConnection.this.mXmppConnectionService.getNotificationService().push(message);
 			}
 		}
 

src/eu/siacs/conversations/parser/MessageParser.java 🔗

@@ -487,6 +487,7 @@ public class MessageParser extends AbstractParser implements
 		if (message.bodyContainsDownloadable()) {
 			this.mXmppConnectionService.getHttpConnectionManager()
 					.createNewConnection(message);
+			notify = false;
 		}
 		notify = notify && !conversation.isMuted();
 		if (notify) {

src/eu/siacs/conversations/services/NotificationService.java 🔗

@@ -13,14 +13,17 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.net.Uri;
 import android.os.PowerManager;
+import android.os.SystemClock;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.TaskStackBuilder;
 import android.text.Html;
 import android.util.DisplayMetrics;
 
+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.Downloadable;
 import eu.siacs.conversations.entities.Message;
 import eu.siacs.conversations.ui.ConversationActivity;
 
@@ -30,9 +33,10 @@ public class NotificationService {
 
 	private LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<String, ArrayList<Message>>();
 
-	public int NOTIFICATION_ID = 0x2342;
+	public static int NOTIFICATION_ID = 0x2342;
 	private Conversation mOpenConversation;
 	private boolean mIsInForeground;
+	private long mLastNotification;
 
 	public NotificationService(XmppConnectionService service) {
 		this.mXmppConnectionService = service;
@@ -58,7 +62,8 @@ public class NotificationService {
 			}
 			Account account = message.getConversation().getAccount();
 			updateNotification((!(this.mIsInForeground && this.mOpenConversation == null) || !isScreenOn)
-					&& !account.inGracePeriod());
+					&& !account.inGracePeriod()
+					&& !this.inMiniGracePeriod(account));
 		}
 
 	}
@@ -89,6 +94,9 @@ public class NotificationService {
 		if (notifications.size() == 0) {
 			notificationManager.cancel(NOTIFICATION_ID);
 		} else {
+			if (notify) {
+				this.markLastNotification();
+			}
 			NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
 					mXmppConnectionService);
 			mBuilder.setSmallIcon(R.drawable.ic_notification);
@@ -103,19 +111,17 @@ public class NotificationService {
 					mBuilder.setContentTitle(conversation.getName());
 					StringBuilder text = new StringBuilder();
 					for (int i = 0; i < messages.size(); ++i) {
-						text.append(messages.get(i).getReadableBody(
-								mXmppConnectionService));
+						text.append(getReadableBody(messages.get(i)));
 						if (i != messages.size() - 1) {
 							text.append("\n");
 						}
 					}
 					mBuilder.setStyle(new NotificationCompat.BigTextStyle()
 							.bigText(text.toString()));
-					mBuilder.setContentText(messages.get(0).getReadableBody(
-							mXmppConnectionService));
+					mBuilder.setContentText(getReadableBody(messages.get(0)));
 					if (notify) {
-						mBuilder.setTicker(messages.get(messages.size() - 1)
-								.getReadableBody(mXmppConnectionService));
+						mBuilder.setTicker(getReadableBody(messages
+								.get(messages.size() - 1)));
 					}
 					mBuilder.setContentIntent(createContentIntent(conversation
 							.getUuid()));
@@ -135,11 +141,8 @@ public class NotificationService {
 					if (messages.size() > 0) {
 						conversation = messages.get(0).getConversation();
 						String name = conversation.getName();
-						style.addLine(Html.fromHtml("<b>"
-								+ name
-								+ "</b> "
-								+ messages.get(0).getReadableBody(
-										mXmppConnectionService)));
+						style.addLine(Html.fromHtml("<b>" + name + "</b> "
+								+ getReadableBody(messages.get(0))));
 						names.append(name);
 						names.append(", ");
 					}
@@ -175,6 +178,26 @@ public class NotificationService {
 		}
 	}
 
+	private String getReadableBody(Message message) {
+		if (message.getDownloadable() != null
+				&& (message.getDownloadable().getStatus() == Downloadable.STATUS_OFFER || message
+						.getDownloadable().getStatus() == Downloadable.STATUS_OFFER_CHECK_FILESIZE)) {
+			return mXmppConnectionService.getText(
+					R.string.image_offered_for_download).toString();
+		} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
+			return mXmppConnectionService.getText(
+					R.string.encrypted_message_received).toString();
+		} else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
+			return mXmppConnectionService.getText(R.string.decryption_failed)
+					.toString();
+		} else if (message.getType() == Message.TYPE_IMAGE) {
+			return mXmppConnectionService.getText(R.string.image_file)
+					.toString();
+		} else {
+			return message.getBody().trim();
+		}
+	}
+
 	private PendingIntent createContentIntent(String conversationUuid) {
 		TaskStackBuilder stackBuilder = TaskStackBuilder
 				.create(mXmppConnectionService);
@@ -234,4 +257,14 @@ public class NotificationService {
 				.getDisplayMetrics();
 		return ((int) (dp * metrics.density));
 	}
+
+	private void markLastNotification() {
+		this.mLastNotification = SystemClock.elapsedRealtime();
+	}
+
+	private boolean inMiniGracePeriod(Account account) {
+		int miniGrace = account.getStatus() == Account.STATUS_ONLINE ? Config.MINI_GRACE_PERIOD
+				: Config.MINI_GRACE_PERIOD * 2;
+		return SystemClock.elapsedRealtime() < (this.mLastNotification + miniGrace);
+	}
 }

src/eu/siacs/conversations/ui/adapter/ConversationAdapter.java 🔗

@@ -78,14 +78,14 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
 		if (message.getType() == Message.TYPE_IMAGE
 				|| message.getDownloadable() != null) {
 			Downloadable d = message.getDownloadable();
+			if (conversation.isRead()) {
+				mLastMessage.setTypeface(null, Typeface.ITALIC);
+			} else {
+				mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC);
+			}
 			if (d != null) {
 				mLastMessage.setVisibility(View.VISIBLE);
 				imagePreview.setVisibility(View.GONE);
-				if (conversation.isRead()) {
-					mLastMessage.setTypeface(null, Typeface.ITALIC);
-				} else {
-					mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC);
-				}
 				if (d.getStatus() == Downloadable.STATUS_CHECKING) {
 					mLastMessage.setText(R.string.checking_image);
 				} else if (d.getStatus() == Downloadable.STATUS_DOWNLOADING) {
@@ -99,6 +99,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
 				} else {
 					mLastMessage.setText("");
 				}
+			} else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
+				mLastMessage.setText(R.string.encrypted_message_received);
 			} else {
 				mLastMessage.setVisibility(View.GONE);
 				imagePreview.setVisibility(View.VISIBLE);