do not crash when error notification comes after service has shut down

This commit is contained in:
Daniel Gultsch 2024-03-27 14:44:17 +01:00
parent fbfb6c803f
commit 378efe1a8a
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2

View file

@ -2,6 +2,7 @@ package eu.siacs.conversations.services;
import static eu.siacs.conversations.utils.Compatibility.s; import static eu.siacs.conversations.utils.Compatibility.s;
import android.Manifest;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.app.NotificationChannelGroup; import android.app.NotificationChannelGroup;
@ -10,6 +11,7 @@ import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutManager; import android.content.pm.ShortcutManager;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -29,6 +31,7 @@ import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationCompat.BigPictureStyle; import androidx.core.app.NotificationCompat.BigPictureStyle;
import androidx.core.app.NotificationCompat.Builder; import androidx.core.app.NotificationCompat.Builder;
@ -1694,8 +1697,7 @@ public class NotificationService {
} }
private boolean wasHighlightedOrPrivate(final Message message) { private boolean wasHighlightedOrPrivate(final Message message) {
if (message.getConversation() instanceof Conversation) { if (message.getConversation() instanceof Conversation conversation) {
Conversation conversation = (Conversation) message.getConversation();
final String nick = conversation.getMucOptions().getActualNick(); final String nick = conversation.getMucOptions().getActualNick();
final Pattern highlight = generateNickHighlightPattern(nick); final Pattern highlight = generateNickHighlightPattern(nick);
if (message.getBody() == null || nick == null) { if (message.getBody() == null || nick == null) {
@ -1825,10 +1827,17 @@ public class NotificationService {
} }
} }
if (mXmppConnectionService.foregroundNotificationNeedsUpdatingWhenErrorStateChanges()) { if (mXmppConnectionService.foregroundNotificationNeedsUpdatingWhenErrorStateChanges()) {
notify(FOREGROUND_NOTIFICATION_ID, createForegroundNotification()); try {
notify(FOREGROUND_NOTIFICATION_ID, createForegroundNotification());
} catch (final RuntimeException e) {
Log.d(
Config.LOGTAG,
"not refreshing foreground service notification because service has died",
e);
}
} }
final Notification.Builder mBuilder = new Notification.Builder(mXmppConnectionService); final Notification.Builder mBuilder = new Notification.Builder(mXmppConnectionService);
if (errors.size() == 0) { if (errors.isEmpty()) {
cancel(ERROR_NOTIFICATION_ID); cancel(ERROR_NOTIFICATION_ID);
return; return;
} else if (errors.size() == 1) { } else if (errors.size() == 1) {
@ -1840,10 +1849,23 @@ public class NotificationService {
mXmppConnectionService.getString(R.string.problem_connecting_to_accounts)); mXmppConnectionService.getString(R.string.problem_connecting_to_accounts));
mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_fix)); mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_fix));
} }
mBuilder.addAction( try {
R.drawable.ic_autorenew_white_24dp, mBuilder.addAction(
mXmppConnectionService.getString(R.string.try_again), R.drawable.ic_autorenew_white_24dp,
pendingServiceIntent(mXmppConnectionService, XmppConnectionService.ACTION_TRY_AGAIN, 45)); mXmppConnectionService.getString(R.string.try_again),
pendingServiceIntent(
mXmppConnectionService, XmppConnectionService.ACTION_TRY_AGAIN, 45));
mBuilder.setDeleteIntent(
pendingServiceIntent(
mXmppConnectionService,
XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS,
69));
} catch (final RuntimeException e) {
Log.d(
Config.LOGTAG,
"not including some actions in error notification because service has died",
e);
}
if (torNotAvailable) { if (torNotAvailable) {
if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) { if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) {
mBuilder.addAction( mBuilder.addAction(
@ -1871,7 +1893,6 @@ public class NotificationService {
: PendingIntent.FLAG_UPDATE_CURRENT)); : PendingIntent.FLAG_UPDATE_CURRENT));
} }
} }
mBuilder.setDeleteIntent(pendingServiceIntent(mXmppConnectionService,XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS, 69));
mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE); mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp); mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
mBuilder.setLocalOnly(true); mBuilder.setLocalOnly(true);
@ -1912,27 +1933,37 @@ public class NotificationService {
notify(FOREGROUND_NOTIFICATION_ID, notification); notify(FOREGROUND_NOTIFICATION_ID, notification);
} }
private void notify(String tag, int id, Notification notification) { private void notify(final String tag, final int id, final Notification notification) {
final NotificationManagerCompat notificationManager = if (ActivityCompat.checkSelfPermission(
NotificationManagerCompat.from(mXmppConnectionService); mXmppConnectionService, Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
final var notificationManager =
mXmppConnectionService.getSystemService(NotificationManager.class);
try { try {
notificationManager.notify(tag, id, notification); notificationManager.notify(tag, id, notification);
} catch (RuntimeException e) { } catch (final RuntimeException e) {
Log.d(Config.LOGTAG, "unable to make notification", e); Log.d(Config.LOGTAG, "unable to make notification", e);
} }
} }
public void notify(int id, Notification notification) { public void notify(final int id, final Notification notification) {
final NotificationManagerCompat notificationManager = if (ActivityCompat.checkSelfPermission(
NotificationManagerCompat.from(mXmppConnectionService); mXmppConnectionService, Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
final var notificationManager =
mXmppConnectionService.getSystemService(NotificationManager.class);
try { try {
notificationManager.notify(id, notification); notificationManager.notify(id, notification);
} catch (RuntimeException e) { } catch (final RuntimeException e) {
Log.d(Config.LOGTAG, "unable to make notification", e); Log.d(Config.LOGTAG, "unable to make notification", e);
} }
} }
public void cancel(int id) { public void cancel(final int id) {
final NotificationManagerCompat notificationManager = final NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(mXmppConnectionService); NotificationManagerCompat.from(mXmppConnectionService);
try { try {