use distinct notification id for video transcoder

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/services/AttachFileToConversationRunnable.java | 12 
src/main/java/eu/siacs/conversations/services/NotificationService.java              | 37 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java            | 52 
3 files changed, 65 insertions(+), 36 deletions(-)

Detailed changes

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

@@ -90,7 +90,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
 
     private void processAsVideo() throws FileNotFoundException {
         Log.d(Config.LOGTAG, "processing file as video");
-        mXmppConnectionService.startForcingForegroundNotification();
+        mXmppConnectionService.startOngoingVideoTranscodingForegroundNotification();
         mXmppConnectionService.getFileBackend().setupRelativeFilePath(message, String.format("%s.%s", message.getUuid(), "mp4"));
         final DownloadableFile file = mXmppConnectionService.getFileBackend().getFile(message);
         if (Objects.requireNonNull(file.getParentFile()).mkdirs()) {
@@ -109,7 +109,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
                 .transcode();
         } catch (final RuntimeException e) {
             // transcode can already throw if there is an invalid file format or a platform bug
-            mXmppConnectionService.stopForcingForegroundNotification();
+            mXmppConnectionService.stopOngoingVideoTranscodingForegroundNotification();
             processAsFile();
             return;
         }
@@ -119,7 +119,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
             throw new AssertionError(e);
         } catch (final ExecutionException e) {
             if (e.getCause() instanceof Error) {
-                mXmppConnectionService.stopForcingForegroundNotification();
+                mXmppConnectionService.stopOngoingVideoTranscodingForegroundNotification();
                 processAsFile();
             } else {
                 Log.d(Config.LOGTAG, "ignoring execution exception. Should get handled by onTranscodeFiled() instead", e);
@@ -138,7 +138,7 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
 
     @Override
     public void onTranscodeCompleted(int successCode) {
-        mXmppConnectionService.stopForcingForegroundNotification();
+        mXmppConnectionService.stopOngoingVideoTranscodingForegroundNotification();
         final File file = mXmppConnectionService.getFileBackend().getFile(message);
         long convertedFileSize = mXmppConnectionService.getFileBackend().getFile(message).getSize();
         Log.d(Config.LOGTAG, "originalFileSize=" + originalFileSize + " convertedFileSize=" + convertedFileSize);
@@ -162,13 +162,13 @@ public class AttachFileToConversationRunnable implements Runnable, TranscoderLis
 
     @Override
     public void onTranscodeCanceled() {
-        mXmppConnectionService.stopForcingForegroundNotification();
+        mXmppConnectionService.stopOngoingVideoTranscodingForegroundNotification();
         processAsFile();
     }
 
     @Override
     public void onTranscodeFailed(@NonNull @NotNull Throwable exception) {
-        mXmppConnectionService.stopForcingForegroundNotification();
+        mXmppConnectionService.stopOngoingVideoTranscodingForegroundNotification();
         Log.d(Config.LOGTAG, "video transcoding failed", exception);
         processAsFile();
     }

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

@@ -30,6 +30,7 @@ import android.text.style.StyleSpan;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.core.app.ActivityCompat;
 import androidx.core.app.NotificationCompat;
@@ -108,6 +109,7 @@ public class NotificationService {
     public static final int ONGOING_CALL_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 10;
     public static final int MISSED_CALL_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 12;
     private static final int DELIVERY_FAILED_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 13;
+    public static final int ONGOING_VIDEO_TRANSCODING_NOTIFICATION_ID = NOTIFICATION_ID_MULTIPLIER * 14;
     private final XmppConnectionService mXmppConnectionService;
     private final LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<>();
     private final HashMap<Conversation, AtomicInteger> mBacklogMessageCounter = new HashMap<>();
@@ -1919,18 +1921,33 @@ public class NotificationService {
         notify(ERROR_NOTIFICATION_ID, mBuilder.build());
     }
 
-    void updateFileAddingNotification(int current, Message message) {
-        Notification.Builder mBuilder = new Notification.Builder(mXmppConnectionService);
-        mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.transcoding_video));
-        mBuilder.setProgress(100, current, false);
-        mBuilder.setSmallIcon(R.drawable.ic_hourglass_empty_white_24dp);
-        mBuilder.setContentIntent(createContentIntent(message.getConversation()));
-        mBuilder.setOngoing(true);
+    void updateFileAddingNotification(final int current, final Message message) {
+
+        final Notification notification = videoTranscoding(current, message);
+        notify(ONGOING_VIDEO_TRANSCODING_NOTIFICATION_ID, notification);
+    }
+
+    private Notification videoTranscoding(final int current, @Nullable final Message message) {
+        final Notification.Builder builder = new Notification.Builder(mXmppConnectionService);
+        builder.setContentTitle(mXmppConnectionService.getString(R.string.transcoding_video));
+        if (current >= 0) {
+            builder.setProgress(100, current, false);
+        } else {
+            builder.setProgress(100, 0, true);
+        }
+        builder.setSmallIcon(R.drawable.ic_hourglass_empty_white_24dp);
+        if (message != null) {
+            builder.setContentIntent(createContentIntent(message.getConversation()));
+        }
+        builder.setOngoing(true);
         if (Compatibility.runsTwentySix()) {
-            mBuilder.setChannelId("compression");
+            builder.setChannelId("compression");
         }
-        Notification notification = mBuilder.build();
-        notify(FOREGROUND_NOTIFICATION_ID, notification);
+        return builder.build();
+    }
+
+    public Notification getIndeterminateVideoTranscoding() {
+        return videoTranscoding(-1, null);
     }
 
     private void notify(final String tag, final int id, final Notification notification) {

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

@@ -243,7 +243,7 @@ public class XmppConnectionService extends Service {
     private final ChannelDiscoveryService mChannelDiscoveryService = new ChannelDiscoveryService(this);
     private final ShortcutService mShortcutService = new ShortcutService(this);
     private final AtomicBoolean mInitialAddressbookSyncCompleted = new AtomicBoolean(false);
-    private final AtomicBoolean mForceForegroundService = new AtomicBoolean(false);
+    private final AtomicBoolean mOngoingVideoTranscoding = new AtomicBoolean(false);
     private final AtomicBoolean mForceDuringOnCreate = new AtomicBoolean(false);
     private final AtomicReference<OngoingCall> ongoingCall = new AtomicReference<>();
     private final OnMessagePacketReceived mMessageParser = new MessageParser(this);
@@ -526,13 +526,13 @@ public class XmppConnectionService extends Service {
         }
     }
 
-    public void startForcingForegroundNotification() {
-        mForceForegroundService.set(true);
+    public void startOngoingVideoTranscodingForegroundNotification() {
+        mOngoingVideoTranscoding.set(true);
         toggleForegroundService();
     }
 
-    public void stopForcingForegroundNotification() {
-        mForceForegroundService.set(false);
+    public void stopOngoingVideoTranscodingForegroundNotification() {
+        mOngoingVideoTranscoding.set(false);
         toggleForegroundService();
     }
 
@@ -1467,35 +1467,47 @@ public class XmppConnectionService extends Service {
     private void toggleForegroundService(final boolean force) {
         final boolean status;
         final OngoingCall ongoing = ongoingCall.get();
-        if (force || mForceDuringOnCreate.get() || mForceForegroundService.get() || ongoing != null || (Compatibility.keepForegroundService(this) && hasEnabledAccounts())) {
+        final boolean ongoingVideoTranscoding = mOngoingVideoTranscoding.get();
+        final int id;
+        if (force
+                || mForceDuringOnCreate.get()
+                || ongoingVideoTranscoding
+                || ongoing != null
+                || (Compatibility.keepForegroundService(this) && hasEnabledAccounts())) {
             final Notification notification;
-            final int id;
             if (ongoing != null) {
                 notification = this.mNotificationService.getOngoingCallNotification(ongoing);
                 id = NotificationService.ONGOING_CALL_NOTIFICATION_ID;
                 startForegroundOrCatch(id, notification, true);
-                mNotificationService.cancel(NotificationService.FOREGROUND_NOTIFICATION_ID);
+            } else if (ongoingVideoTranscoding) {
+                notification = this.mNotificationService.getIndeterminateVideoTranscoding();
+                id = NotificationService.ONGOING_VIDEO_TRANSCODING_NOTIFICATION_ID;
+                startForegroundOrCatch(id, notification, false);
             } else {
                 notification = this.mNotificationService.createForegroundNotification();
                 id = NotificationService.FOREGROUND_NOTIFICATION_ID;
                 startForegroundOrCatch(id, notification, false);
             }
-
-            if (!mForceForegroundService.get()) {
-                mNotificationService.notify(id, notification);
-            }
+            mNotificationService.notify(id, notification);
             status = true;
         } else {
+            id = 0;
             stopForeground(true);
             status = false;
         }
-        if (!mForceForegroundService.get()) {
-            mNotificationService.cancel(NotificationService.FOREGROUND_NOTIFICATION_ID);
-        }
-        if (ongoing == null) {
-            mNotificationService.cancel(NotificationService.ONGOING_CALL_NOTIFICATION_ID);
+
+        for (final int toBeRemoved :
+                Collections2.filter(
+                        Arrays.asList(
+                                NotificationService.FOREGROUND_NOTIFICATION_ID,
+                                NotificationService.ONGOING_CALL_NOTIFICATION_ID,
+                                NotificationService.ONGOING_VIDEO_TRANSCODING_NOTIFICATION_ID),
+                        i -> i != id)) {
+            mNotificationService.cancel(toBeRemoved);
         }
-        Log.d(Config.LOGTAG, "ForegroundService: " + (status ? "on" : "off"));
+        Log.d(
+                Config.LOGTAG,
+                "ForegroundService: " + (status ? "on" : "off") + ", notification: " + id);
     }
 
     private void startForegroundOrCatch(
@@ -1531,13 +1543,13 @@ public class XmppConnectionService extends Service {
     }
 
     public boolean foregroundNotificationNeedsUpdatingWhenErrorStateChanges() {
-        return !mForceForegroundService.get() && ongoingCall.get() == null && Compatibility.keepForegroundService(this) && hasEnabledAccounts();
+        return !mOngoingVideoTranscoding.get() && ongoingCall.get() == null && Compatibility.keepForegroundService(this) && hasEnabledAccounts();
     }
 
     @Override
     public void onTaskRemoved(final Intent rootIntent) {
         super.onTaskRemoved(rootIntent);
-        if ((Compatibility.keepForegroundService(this) && hasEnabledAccounts()) || mForceForegroundService.get() || ongoingCall.get() != null) {
+        if ((Compatibility.keepForegroundService(this) && hasEnabledAccounts()) || mOngoingVideoTranscoding.get() || ongoingCall.get() != null) {
             Log.d(Config.LOGTAG, "ignoring onTaskRemoved because foreground service is activated");
         } else {
             this.logoutAndSave(false);