make error notification dismissable. fixes #1815

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Account.java               | 11 
src/main/java/eu/siacs/conversations/services/NotificationService.java   | 37 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 39 
3 files changed, 47 insertions(+), 40 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Account.java 🔗

@@ -91,6 +91,17 @@ public class Account extends AbstractEntity {
 		return pgpDecryptionService != null && pgpDecryptionService.isConnected();
 	}
 
+	public boolean setShowErrorNotification(boolean newValue) {
+		boolean oldValue = showErrorNotification();
+		setKey("show_error",Boolean.toString(newValue));
+		return newValue != oldValue;
+	}
+
+	public boolean showErrorNotification() {
+		String key = getKey("show_error");
+		return key == null || Boolean.parseBoolean(key);
+	}
+
 	public enum State {
 		DISABLED,
 		OFFLINE,

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

@@ -2,7 +2,6 @@ package eu.siacs.conversations.services;
 
 import android.app.Notification;
 import android.app.PendingIntent;
-import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.graphics.Bitmap;
@@ -14,18 +13,13 @@ import android.support.v4.app.NotificationCompat.BigPictureStyle;
 import android.support.v4.app.NotificationCompat.Builder;
 import android.support.v4.app.NotificationManagerCompat;
 import android.support.v4.app.RemoteInput;
-import android.support.v4.app.TaskStackBuilder;
 import android.text.Html;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-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 java.util.Map;
@@ -496,11 +490,10 @@ public class NotificationService {
 		return PendingIntent.getService(mXmppConnectionService, 45, intent, 0);
 	}
 
-	private PendingIntent createDisableAccountIntent(final Account account) {
+	private PendingIntent createDismissErrorIntent() {
 		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);
+		intent.setAction(XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS);
+		return PendingIntent.getService(mXmppConnectionService, 69, intent, 0);
 	}
 
 	private boolean wasHighlightedOrPrivate(final Message message) {
@@ -594,7 +587,7 @@ public class NotificationService {
 		final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService);
 		final List<Account> errors = new ArrayList<>();
 		for (final Account account : mXmppConnectionService.getAccounts()) {
-			if (account.hasErrorStatus()) {
+			if (account.hasErrorStatus() && account.showErrorNotification()) {
 				errors.add(account);
 			}
 		}
@@ -615,27 +608,17 @@ public class NotificationService {
 		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);
+		mBuilder.setDeleteIntent(createDismissErrorIntent());
+		mBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
 		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);
+		mBuilder.setContentIntent(PendingIntent.getActivity(mXmppConnectionService,
+				145,
+				new Intent(mXmppConnectionService,ManageAccountActivity.class),
+				PendingIntent.FLAG_UPDATE_CURRENT));
 		notificationManager.notify(ERROR_NOTIFICATION_ID, mBuilder.build());
 	}
 }

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -132,8 +132,8 @@ public class XmppConnectionService extends Service {
 	public static final String ACTION_REPLY_TO_CONVERSATION = "reply_to_conversations";
 	public static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
 	public static final String ACTION_DISABLE_FOREGROUND = "disable_foreground";
+	public static final String ACTION_DISMISS_ERROR_NOTIFICATIONS = "dismiss_error";
 	public static final String ACTION_TRY_AGAIN = "try_again";
-	public static final String ACTION_DISABLE_ACCOUNT = "disable_account";
 	public static final String ACTION_IDLE_PING = "idle_ping";
 	private static final String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
 	public static final String ACTION_GCM_TOKEN_REFRESH = "gcm_token_refresh";
@@ -294,6 +294,9 @@ public class XmppConnectionService extends Service {
 				mOnAccountUpdate.onAccountUpdate();
 			}
 			if (account.getStatus() == Account.State.ONLINE) {
+				if (account.setShowErrorNotification(true)) {
+					databaseBackend.updateAccount(account);
+				}
 				mMessageArchiveService.executePendingQueries(account);
 				if (connection != null && connection.getFeatures().csi()) {
 					if (checkListeners()) {
@@ -554,22 +557,13 @@ public class XmppConnectionService extends Service {
 					getPreferences().edit().putBoolean("keep_foreground_service", false).commit();
 					toggleForegroundService();
 					break;
+				case ACTION_DISMISS_ERROR_NOTIFICATIONS:
+					dismissErrorNotifications();
+					break;
 				case ACTION_TRY_AGAIN:
 					resetAllAttemptCounts(false);
 					interactive = true;
 					break;
-				case ACTION_DISABLE_ACCOUNT:
-					try {
-						String jid = intent.getStringExtra("account");
-						Account account = jid == null ? null : findAccountByJid(Jid.fromString(jid));
-						if (account != null) {
-							account.setOption(Account.OPTION_DISABLED, true);
-							updateAccount(account);
-						}
-					} catch (final InvalidJidException ignored) {
-						break;
-					}
-					break;
 				case ACTION_REPLY_TO_CONVERSATION:
 					Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
 					if (remoteInput != null && c != null) {
@@ -811,6 +805,20 @@ public class XmppConnectionService extends Service {
 					connection.resetAttemptCount();
 				}
 			}
+			if (account.setShowErrorNotification(true)) {
+				databaseBackend.updateAccount(account);
+			}
+		}
+	}
+
+	private void dismissErrorNotifications() {
+		for (final Account account : this.accounts) {
+			if (account.hasErrorStatus()) {
+				Log.d(Config.LOGTAG,account.getJid().toBareJid()+": dismissing error notification");
+				if (account.setShowErrorNotification(false)) {
+					databaseBackend.updateAccount(account);
+				}
+			}
 		}
 	}
 
@@ -1027,6 +1035,10 @@ public class XmppConnectionService extends Service {
 
 	private void sendMessage(final Message message, final boolean resend, final boolean delay) {
 		final Account account = message.getConversation().getAccount();
+		if (account.setShowErrorNotification(true)) {
+			databaseBackend.updateAccount(account);
+			mNotificationService.updateErrorNotification();
+		}
 		final Conversation conversation = message.getConversation();
 		account.deactivateGracePeriod();
 		MessagePacket packet = null;
@@ -1651,6 +1663,7 @@ public class XmppConnectionService extends Service {
 
 	public boolean updateAccount(final Account account) {
 		if (databaseBackend.updateAccount(account)) {
+			account.setShowErrorNotification(true);
 			this.statusListener.onStatusChanged(account);
 			databaseBackend.updateAccount(account);
 			reconnectAccountInBackground(account);