fix crash from non-existant notification channel

Phillip Davis created

ticket: https://todo.sr.ht/~singpolyma/soprani.ca/502

Change summary

build.gradle                                                               |  6 
src/cheogram/java/com/cheogram/android/DownloadDefaultStickers.java        |  5 
src/cheogram/java/eu/siacs/conversations/services/ImportBackupService.java |  4 
src/main/java/eu/siacs/conversations/services/NotificationService.java     | 14 
src/test/java/com/cheogram/android/DownloadDefaultStickersTest.java        | 36 
src/test/java/eu/siacs/conversations/services/ImportBackupServiceTest.java | 36 
src/test/resources/robolectric.properties                                  |  1 
7 files changed, 100 insertions(+), 2 deletions(-)

Detailed changes

build.gradle 🔗

@@ -293,6 +293,12 @@ android {
         abortOnError false
     }
 
+    testOptions {
+        unitTests {
+            includeAndroidResources = true
+        }
+    }
+
     subprojects {
 
         afterEvaluate {

src/cheogram/java/com/cheogram/android/DownloadDefaultStickers.java 🔗

@@ -45,6 +45,7 @@ import eu.siacs.conversations.entities.Message;
 import eu.siacs.conversations.http.HttpConnectionManager;
 import eu.siacs.conversations.persistance.DatabaseBackend;
 import eu.siacs.conversations.persistance.FileBackend;
+import eu.siacs.conversations.services.NotificationService;
 import eu.siacs.conversations.utils.Compatibility;
 import eu.siacs.conversations.utils.FileUtils;
 import eu.siacs.conversations.utils.MimeUtils;
@@ -61,8 +62,10 @@ public class DownloadDefaultStickers extends Service {
 
 	@Override
 	public void onCreate() {
-		mDatabaseBackend = DatabaseBackend.getInstance(getBaseContext());
 		notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+		NotificationService.ensureChannelExists(
+				notificationManager, "backup", getString(R.string.backup_channel_name), NotificationManager.IMPORTANCE_LOW);
+		mDatabaseBackend = DatabaseBackend.getInstance(getBaseContext());
 		mStickerDir = stickerDir();
 	}
 

src/cheogram/java/eu/siacs/conversations/services/ImportBackupService.java 🔗

@@ -83,8 +83,10 @@ public class ImportBackupService extends Service {
 
     @Override
     public void onCreate() {
+        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+        NotificationService.ensureChannelExists(
+                notificationManager, "backup", getString(R.string.backup_channel_name), NotificationManager.IMPORTANCE_LOW);
         mDatabaseBackend = DatabaseBackend.getInstance(getBaseContext());
-        notificationManager = (android.app.NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
     }
 
     @Override

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

@@ -162,6 +162,20 @@ public class NotificationService {
                 && message.getFileParams().height > 0;
     }
 
+    public static void ensureChannelExists(
+            final NotificationManager notificationManager,
+            final String channelId,
+            final String channelName,
+            final int importance) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            return;
+        }
+        final NotificationChannel channel =
+                new NotificationChannel(channelId, channelName, importance);
+        channel.setShowBadge(false);
+        notificationManager.createNotificationChannel(channel);
+    }
+
     @RequiresApi(api = Build.VERSION_CODES.O)
     void initializeChannels() {
         final Context c = mXmppConnectionService;

src/test/java/com/cheogram/android/DownloadDefaultStickersTest.java 🔗

@@ -0,0 +1,36 @@
+package com.cheogram.android;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.ConscryptMode;
+
+import eu.siacs.conversations.Conversations;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(sdk = Build.VERSION_CODES.TIRAMISU, application = Conversations.class)
+@ConscryptMode(ConscryptMode.Mode.OFF)
+public class DownloadDefaultStickersTest {
+
+    @Test
+    public void testBackupChannelExistsAfterOnCreate() {
+        Robolectric.buildService(DownloadDefaultStickers.class).create().get();
+
+        NotificationManager nm = (NotificationManager)
+                RuntimeEnvironment.getApplication()
+                        .getSystemService(Context.NOTIFICATION_SERVICE);
+
+        NotificationChannel channel = nm.getNotificationChannel("backup");
+        assertNotNull("backup channel should exist after onCreate", channel);
+    }
+}

src/test/java/eu/siacs/conversations/services/ImportBackupServiceTest.java 🔗

@@ -0,0 +1,36 @@
+package eu.siacs.conversations.services;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Build;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.ConscryptMode;
+
+import eu.siacs.conversations.Conversations;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(sdk = Build.VERSION_CODES.TIRAMISU, application = Conversations.class)
+@ConscryptMode(ConscryptMode.Mode.OFF)
+public class ImportBackupServiceTest {
+
+    @Test
+    public void testBackupChannelExistsAfterOnCreate() {
+        Robolectric.buildService(ImportBackupService.class).create().get();
+
+        NotificationManager nm = (NotificationManager)
+                RuntimeEnvironment.getApplication()
+                        .getSystemService(Context.NOTIFICATION_SERVICE);
+
+        NotificationChannel channel = nm.getNotificationChannel("backup");
+        assertNotNull("backup channel should exist after onCreate", channel);
+    }
+}