From 0c98d4d9b785deac035d31cfbbd6c91e0a3a0450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Fri, 10 Sep 2021 14:13:50 -0400 Subject: [PATCH] fix data transfer notification Change-Id: I7173ca5cb916179cd51ddc8d5e4910dbfd812a9f --- .../cx/ring/services/DataTransferService.java | 122 ------------------ .../cx/ring/services/DataTransferService.kt | 116 +++++++++++++++++ .../ring/services/NotificationServiceImpl.kt | 108 ++++------------ .../net/jami/services/NotificationService.kt | 2 +- 4 files changed, 145 insertions(+), 203 deletions(-) delete mode 100644 ring-android/app/src/main/java/cx/ring/services/DataTransferService.java create mode 100644 ring-android/app/src/main/java/cx/ring/services/DataTransferService.kt diff --git a/ring-android/app/src/main/java/cx/ring/services/DataTransferService.java b/ring-android/app/src/main/java/cx/ring/services/DataTransferService.java deleted file mode 100644 index 148b540d8..000000000 --- a/ring-android/app/src/main/java/cx/ring/services/DataTransferService.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2004-2021 Savoir-faire Linux Inc. - * - * Author: Rayan Osseiran <rayan.osseiran@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -package cx.ring.services; - -import android.app.Notification; -import android.app.Service; -import android.content.Intent; -import android.content.pm.ServiceInfo; -import android.os.Build; -import android.os.IBinder; -import android.util.Log; - -import androidx.annotation.Nullable; -import androidx.core.app.NotificationManagerCompat; - -import javax.inject.Inject; - -import dagger.hilt.android.AndroidEntryPoint; - -import net.jami.services.NotificationService; - -import java.util.HashSet; -import java.util.Set; - -@AndroidEntryPoint -public class DataTransferService extends Service { - private final String TAG = DataTransferService.class.getSimpleName(); - public static final String ACTION_START = "startTransfer"; - public static final String ACTION_STOP = "stopTransfer"; - private static final int NOTIF_FILE_SERVICE_ID = 1002; - - @Inject - NotificationService mNotificationService; - - private NotificationManagerCompat notificationManager; - private boolean started = false; - - private int serviceNotificationId = 0; - private final Set<Integer> serviceNotifications = new HashSet<>(); - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - int notificationId = intent.getIntExtra(NotificationService.KEY_NOTIFICATION_ID, -1); - String action = intent.getAction(); - if (ACTION_START.equals(action)) { - serviceNotifications.add(notificationId); - Notification notification = (Notification) mNotificationService.getDataTransferNotification(notificationId); - // Log.w(TAG, "Updating notification " + intent); - if (!started) { - Log.w(TAG, "starting transfer service " + intent); - serviceNotificationId = notificationId; - started = true; - } - if (notificationId == serviceNotificationId) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) - startForeground(NOTIF_FILE_SERVICE_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC); - else - startForeground(NOTIF_FILE_SERVICE_ID, notification); - } else { - notificationManager.notify(notificationId, notification); - } - } - else if (ACTION_STOP.equals(action)) { - serviceNotifications.remove(notificationId); - if (notificationId == serviceNotificationId) { - // The service notification is removed. Migrate service to other notification or stop it - serviceNotificationId = serviceNotifications.isEmpty() ? 0 : serviceNotifications.iterator().next(); - if (serviceNotificationId == 0) { - Log.w(TAG, "stopping transfer service " + intent); - stopForeground(true); - stopSelf(); - started = false; - } else { - // migrate notification to service - notificationManager.cancel(serviceNotificationId); - Notification notification = (Notification) mNotificationService.getDataTransferNotification(serviceNotificationId); - notificationManager.notify(NOTIF_FILE_SERVICE_ID, notification); - } - } else { - notificationManager.cancel(notificationId); - } - } - return START_NOT_STICKY; - } - - @Override - public void onCreate() { - Log.d(TAG, "OnCreate(), DataTransferService has been initialized"); - notificationManager = NotificationManagerCompat.from(this); - super.onCreate(); - } - - - @Override - public void onDestroy() { - Log.d(TAG, "OnDestroy(), DataTransferService has been destroyed"); - super.onDestroy(); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } -} \ No newline at end of file diff --git a/ring-android/app/src/main/java/cx/ring/services/DataTransferService.kt b/ring-android/app/src/main/java/cx/ring/services/DataTransferService.kt new file mode 100644 index 000000000..faa469a67 --- /dev/null +++ b/ring-android/app/src/main/java/cx/ring/services/DataTransferService.kt @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2004-2021 Savoir-faire Linux Inc. + * + * Author: Rayan Osseiran <rayan.osseiran@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +package cx.ring.services + +import android.app.Notification +import android.app.Service +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject +import net.jami.services.NotificationService +import androidx.core.app.NotificationManagerCompat +import android.content.Intent +import android.content.pm.ServiceInfo +import android.os.Build +import android.os.IBinder +import android.util.Log +import java.util.HashSet + +@AndroidEntryPoint +class DataTransferService : Service() { + @Inject + lateinit var mNotificationService: NotificationService + private var notificationManager: NotificationManagerCompat = NotificationManagerCompat.from(this) + private var started = false + private var serviceNotificationId = 0 + private val serviceNotifications: MutableSet<Int> = HashSet() + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + val notificationId = intent.getIntExtra(NotificationService.KEY_NOTIFICATION_ID, -1) + val action = intent.action + if (ACTION_START == action) { + serviceNotifications.add(notificationId) + val notification = mNotificationService.getDataTransferNotification(notificationId) as Notification + // Log.w(TAG, "Updating notification " + intent); + if (!started) { + Log.w(TAG, "starting transfer service $intent") + serviceNotificationId = notificationId + started = true + } + if (notificationId == serviceNotificationId) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) + startForeground(NOTIF_FILE_SERVICE_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC) + else + startForeground(NOTIF_FILE_SERVICE_ID, notification) + } else { + notificationManager.notify(notificationId, notification) + } + } else if (ACTION_STOP == action) { + serviceNotifications.remove(notificationId) + if (notificationId == serviceNotificationId) { + while (true) { + // The service notification is removed. Migrate service to other notification or stop it + serviceNotificationId = if (serviceNotifications.isEmpty()) 0 else serviceNotifications.iterator().next() + if (serviceNotificationId == 0) { + Log.w(TAG, "stopping transfer service $intent") + stopForeground(true) + stopSelf() + started = false + } else { + // migrate notification to service + notificationManager.cancel(serviceNotificationId) + val notification = mNotificationService.getDataTransferNotification(serviceNotificationId) as Notification? + if (notification != null) { + notificationManager.notify(NOTIF_FILE_SERVICE_ID, notification) + } else { + serviceNotifications.remove(serviceNotificationId) + continue + } + } + break + } + } else { + notificationManager.cancel(notificationId) + } + } + return START_NOT_STICKY + } + + override fun onCreate() { + Log.d(TAG, "OnCreate(), DataTransferService has been initialized") + //notificationManager = NotificationManagerCompat.from(this) + super.onCreate() + } + + override fun onDestroy() { + Log.d(TAG, "OnDestroy(), DataTransferService has been destroyed") + super.onDestroy() + } + + override fun onBind(intent: Intent): IBinder? { + return null + } + + companion object { + const val ACTION_START = "startTransfer" + const val ACTION_STOP = "stopTransfer" + private const val NOTIF_FILE_SERVICE_ID = 1002 + private val TAG = DataTransferService::class.simpleName!! + } +} \ No newline at end of file diff --git a/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.kt b/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.kt index 6ab1389a5..b344beb95 100644 --- a/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.kt +++ b/ring-android/app/src/main/java/cx/ring/services/NotificationServiceImpl.kt @@ -77,6 +77,7 @@ class NotificationServiceImpl( private val currentCalls = LinkedHashMap<String, Conference>() private val callNotifications = ConcurrentHashMap<Int, Notification>() private val dataTransferNotifications = ConcurrentHashMap<Int, Notification>() + @SuppressLint("CheckResult") fun initHelper() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -124,43 +125,30 @@ class NotificationServiceImpl( .addAction( R.drawable.baseline_call_end_24, mContext.getText(R.string.action_call_hangup), - PendingIntent.getService( - mContext, random.nextInt(), + PendingIntent.getService(mContext, random.nextInt(), Intent(DRingService.ACTION_CALL_END) .setClass(mContext, DRingService::class.java) .putExtra(NotificationService.KEY_CALL_ID, call.daemonIdString), - PendingIntent.FLAG_ONE_SHOT - ) + PendingIntent.FLAG_ONE_SHOT) ) } else if (conference.isRinging) { if (conference.isIncoming) { - messageNotificationBuilder = - NotificationCompat.Builder(mContext, NOTIF_CHANNEL_INCOMING_CALL) - messageNotificationBuilder.setContentTitle( - mContext.getString( - R.string.notif_incoming_call_title, - contact.displayName - ) - ) + messageNotificationBuilder = NotificationCompat.Builder(mContext, NOTIF_CHANNEL_INCOMING_CALL) + messageNotificationBuilder.setContentTitle(mContext.getString(R.string.notif_incoming_call_title, contact.displayName)) .setPriority(NotificationCompat.PRIORITY_MAX) .setContentText(mContext.getText(R.string.notif_incoming_call)) .setContentIntent(gotoIntent) .setSound(null) .setVibrate(null) .setFullScreenIntent(gotoIntent, true) - .addAction( - R.drawable.baseline_call_end_24, + .addAction(R.drawable.baseline_call_end_24, mContext.getText(R.string.action_call_decline), - PendingIntent.getService( - mContext, random.nextInt(), + PendingIntent.getService(mContext, random.nextInt(), Intent(DRingService.ACTION_CALL_REFUSE) .setClass(mContext, DRingService::class.java) .putExtra(NotificationService.KEY_CALL_ID, call.daemonIdString), - PendingIntent.FLAG_ONE_SHOT - ) - ) - .addAction( - R.drawable.baseline_call_24, + PendingIntent.FLAG_ONE_SHOT)) + .addAction(R.drawable.baseline_call_24, if (ongoingCallId == null) mContext.getText(R.string.action_call_accept) else @@ -175,18 +163,15 @@ class NotificationServiceImpl( ) ) if (ongoingCallId != null) { - messageNotificationBuilder.addAction( - R.drawable.baseline_call_24, + messageNotificationBuilder.addAction(R.drawable.baseline_call_24, mContext.getText(R.string.action_call_hold_accept), - PendingIntent.getService( - mContext, random.nextInt(), + PendingIntent.getService(mContext, random.nextInt(), Intent(DRingService.ACTION_CALL_HOLD_ACCEPT) .setClass(mContext, DRingService::class.java) .putExtra(NotificationService.KEY_HOLD_ID, ongoingCallId) .putExtra(NotificationService.KEY_CALL_ID, call.daemonIdString), PendingIntent.FLAG_ONE_SHOT - ) - ) + )) } } else { messageNotificationBuilder = NotificationCompat.Builder(mContext, NOTIF_CHANNEL_CALL_IN_PROGRESS) @@ -198,8 +183,7 @@ class NotificationServiceImpl( .setVibrate(null) .setColorized(true) .setColor(ContextCompat.getColor(mContext, R.color.color_primary_light)) - .addAction( - R.drawable.baseline_call_end_24, + .addAction(R.drawable.baseline_call_end_24, mContext.getText(R.string.action_call_hangup), PendingIntent.getService( mContext, random.nextInt(), @@ -207,8 +191,7 @@ class NotificationServiceImpl( .setClass(mContext, DRingService::class.java) .putExtra(NotificationService.KEY_CALL_ID, call.daemonIdString), PendingIntent.FLAG_ONE_SHOT - ) - ) + )) } } else { return null @@ -226,38 +209,19 @@ class NotificationServiceImpl( override fun showLocationNotification(first: Account, contact: Contact) { val path = ConversationPath.toUri(first.accountID, contact.uri) - val intentConversation = - Intent(Intent.ACTION_VIEW, path, mContext, ConversationActivity::class.java) + val intentConversation = Intent(Intent.ACTION_VIEW, path, mContext, ConversationActivity::class.java) .putExtra(ConversationFragment.EXTRA_SHOW_MAP, true) - val messageNotificationBuilder = NotificationCompat.Builder( - mContext, NOTIF_CHANNEL_MESSAGE - ) + val messageNotificationBuilder = NotificationCompat.Builder(mContext, NOTIF_CHANNEL_MESSAGE) .setCategory(NotificationCompat.CATEGORY_MESSAGE) .setPriority(NotificationCompat.PRIORITY_HIGH) .setDefaults(NotificationCompat.DEFAULT_ALL) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setSmallIcon(R.drawable.ic_ring_logo_white) .setLargeIcon(getContactPicture(contact)) - .setContentText( - mContext.getString( - R.string.location_share_contact, - contact.displayName - ) - ) - .setContentIntent( - PendingIntent.getActivity( - mContext, - random.nextInt(), - intentConversation, - 0 - ) - ) + .setContentText(mContext.getString(R.string.location_share_contact, contact.displayName)) + .setContentIntent(PendingIntent.getActivity(mContext, random.nextInt(), intentConversation, 0)) .setAutoCancel(false) - .setColor(ResourcesCompat.getColor( - mContext.resources, - R.color.color_primary_dark, - null - )) + .setColor(ResourcesCompat.getColor(mContext.resources, R.color.color_primary_dark, null)) notificationManager.notify( Objects.hash("Location", path), messageNotificationBuilder.build() @@ -289,10 +253,8 @@ class NotificationServiceImpl( * @param id the notification id */ private fun startForegroundService(id: Int, serviceClass: Class<*>) { - ContextCompat.startForegroundService( - mContext, Intent(mContext, serviceClass) - .putExtra(NotificationService.KEY_NOTIFICATION_ID, id) - ) + ContextCompat.startForegroundService(mContext, Intent(mContext, serviceClass) + .putExtra(NotificationService.KEY_NOTIFICATION_ID, id)) } /** @@ -387,26 +349,12 @@ class NotificationServiceImpl( dataTransferNotifications.remove(id) cancelFileNotification(id, false) if (dataTransferNotifications.isEmpty()) { - mContext.startService( - Intent( - DataTransferService.ACTION_STOP, - path, - mContext, - DataTransferService::class.java - ) - .putExtra(NotificationService.KEY_NOTIFICATION_ID, id) - ) + mContext.startService(Intent(DataTransferService.ACTION_STOP, path, mContext, DataTransferService::class.java) + .putExtra(NotificationService.KEY_NOTIFICATION_ID, id)) } else { - ContextCompat.startForegroundService( - mContext, - Intent( - DataTransferService.ACTION_STOP, - path, - mContext, - DataTransferService::class.java - ) - .putExtra(NotificationService.KEY_NOTIFICATION_ID, id) - ) + ContextCompat.startForegroundService(mContext, + Intent(DataTransferService.ACTION_STOP, path, mContext, DataTransferService::class.java) + .putExtra(NotificationService.KEY_NOTIFICATION_ID, id)) } } @@ -414,8 +362,8 @@ class NotificationServiceImpl( * @param notificationId the notification id * @return the notification object for a data transfer notification */ - override fun getDataTransferNotification(notificationId: Int): Notification { - return dataTransferNotifications[notificationId]!! + override fun getDataTransferNotification(notificationId: Int): Notification? { + return dataTransferNotifications[notificationId] } override fun showTextNotification(accountId: String, conversation: Conversation) { diff --git a/ring-android/libringclient/src/main/java/net/jami/services/NotificationService.kt b/ring-android/libringclient/src/main/java/net/jami/services/NotificationService.kt index 1270afbef..8fdf90af7 100644 --- a/ring-android/libringclient/src/main/java/net/jami/services/NotificationService.kt +++ b/ring-android/libringclient/src/main/java/net/jami/services/NotificationService.kt @@ -36,7 +36,7 @@ interface NotificationService { fun cancelFileNotification(id: Int, isMigratingToService: Boolean) fun handleDataTransferNotification(transfer: DataTransfer, contact: Conversation, remove: Boolean) fun removeTransferNotification(accountId: String, conversationUri: Uri, fileId: String) - fun getDataTransferNotification(notificationId: Int): Any + fun getDataTransferNotification(notificationId: Int): Any? //void updateNotification(Object notification, int notificationId); val serviceNotification: Any -- GitLab