Эх сурвалжийг харах

Fix #713, Fix #720

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 5 жил өмнө
parent
commit
39c2dced64

+ 2 - 3
app/build.gradle

@@ -39,8 +39,8 @@ android {
         targetSdkVersion 28
         targetSdkVersion 28
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 
 
-        versionCode 129
-        versionName "8.0.2"
+        versionCode 130
+        versionName "8.0.3"
 
 
         flavorDimensions "default"
         flavorDimensions "default"
         renderscriptTargetApi 19
         renderscriptTargetApi 19
@@ -253,7 +253,6 @@ dependencies {
     })
     })
     findbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0'
     findbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0'
     findbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.6'
     findbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.6'
-    implementation "com.google.firebase:firebase-messaging:20.1.0"
 }
 }
 
 
 tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
 tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {

+ 106 - 7
app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt

@@ -20,6 +20,7 @@
 package com.nextcloud.talk.services.firebase
 package com.nextcloud.talk.services.firebase
 
 
 import android.annotation.SuppressLint
 import android.annotation.SuppressLint
+import android.app.Notification
 import android.app.PendingIntent
 import android.app.PendingIntent
 import android.content.Intent
 import android.content.Intent
 import android.media.AudioAttributes
 import android.media.AudioAttributes
@@ -40,14 +41,19 @@ import com.google.firebase.messaging.FirebaseMessagingService
 import com.google.firebase.messaging.RemoteMessage
 import com.google.firebase.messaging.RemoteMessage
 import com.nextcloud.talk.R
 import com.nextcloud.talk.R
 import com.nextcloud.talk.activities.MagicCallActivity
 import com.nextcloud.talk.activities.MagicCallActivity
+import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
+import com.nextcloud.talk.events.CallNotificationClick
 import com.nextcloud.talk.jobs.NotificationWorker
 import com.nextcloud.talk.jobs.NotificationWorker
 import com.nextcloud.talk.jobs.PushRegistrationWorker
 import com.nextcloud.talk.jobs.PushRegistrationWorker
 import com.nextcloud.talk.models.RingtoneSettings
 import com.nextcloud.talk.models.RingtoneSettings
 import com.nextcloud.talk.models.SignatureVerification
 import com.nextcloud.talk.models.SignatureVerification
+import com.nextcloud.talk.models.json.participants.Participant
+import com.nextcloud.talk.models.json.participants.ParticipantsOverall
 import com.nextcloud.talk.models.json.push.DecryptedPushMessage
 import com.nextcloud.talk.models.json.push.DecryptedPushMessage
-import com.nextcloud.talk.utils.NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V3
+import com.nextcloud.talk.utils.ApiUtils
+import com.nextcloud.talk.utils.NotificationUtils
 import com.nextcloud.talk.utils.NotificationUtils.cancelAllNotificationsForAccount
 import com.nextcloud.talk.utils.NotificationUtils.cancelAllNotificationsForAccount
 import com.nextcloud.talk.utils.NotificationUtils.cancelExistingNotificationWithId
 import com.nextcloud.talk.utils.NotificationUtils.cancelExistingNotificationWithId
 import com.nextcloud.talk.utils.NotificationUtils.createNotificationChannel
 import com.nextcloud.talk.utils.NotificationUtils.createNotificationChannel
@@ -56,7 +62,17 @@ import com.nextcloud.talk.utils.bundle.BundleKeys
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
 import com.nextcloud.talk.utils.preferences.AppPreferences
 import com.nextcloud.talk.utils.preferences.AppPreferences
+import io.reactivex.Observer
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import okhttp3.JavaNetCookieJar
+import okhttp3.OkHttpClient
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import retrofit2.Retrofit
 import java.io.IOException
 import java.io.IOException
+import java.net.CookieManager
 import java.security.InvalidKeyException
 import java.security.InvalidKeyException
 import java.security.NoSuchAlgorithmException
 import java.security.NoSuchAlgorithmException
 import java.security.PrivateKey
 import java.security.PrivateKey
@@ -70,9 +86,42 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
     @Inject
     @Inject
     var appPreferences: AppPreferences? = null
     var appPreferences: AppPreferences? = null
 
 
+    var isServiceInForeground: Boolean = false
     private var decryptedPushMessage: DecryptedPushMessage? = null
     private var decryptedPushMessage: DecryptedPushMessage? = null
     private var signatureVerification: SignatureVerification? = null
     private var signatureVerification: SignatureVerification? = null
 
 
+    @JvmField
+    @Inject
+    var retrofit: Retrofit? = null
+
+    @JvmField
+    @Inject
+    var okHttpClient: OkHttpClient? = null
+
+    @JvmField
+    @Inject
+    var eventBus: EventBus? = null
+
+
+    override fun onCreate() {
+        super.onCreate()
+        sharedApplication!!.componentApplication.inject(this)
+        eventBus?.register(this)
+    }
+
+    @Subscribe(threadMode = ThreadMode.BACKGROUND)
+    fun onMessageEvent(event: CallNotificationClick) {
+        isServiceInForeground = false
+        stopForeground(true)
+    }
+
+    override fun onDestroy() {
+        isServiceInForeground = false
+        eventBus?.unregister(this)
+        stopForeground(true)
+        super.onDestroy()
+    }
+
     override fun onNewToken(token: String) {
     override fun onNewToken(token: String) {
         super.onNewToken(token)
         super.onNewToken(token)
         sharedApplication!!.componentApplication.inject(this)
         sharedApplication!!.componentApplication.inject(this)
@@ -137,17 +186,22 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
                                 }
                                 }
                             }
                             }
 
 
+                            val notificationChannelId = NotificationUtils.getNotificationChannelId(applicationContext.resources
+                                    .getString(R.string.nc_notification_channel_calls), applicationContext.resources
+                                    .getString(R.string.nc_notification_channel_calls_description), true,
+                                    NotificationManagerCompat.IMPORTANCE_HIGH, soundUri!!, audioAttributesBuilder.build(), NotificationUtils.getVibrationEffectForCalls(), false)
+
                             createNotificationChannel(applicationContext!!,
                             createNotificationChannel(applicationContext!!,
-                                    NOTIFICATION_CHANNEL_CALLS_V3, applicationContext.resources
+                                    notificationChannelId, applicationContext.resources
                                     .getString(R.string.nc_notification_channel_calls), applicationContext.resources
                                     .getString(R.string.nc_notification_channel_calls), applicationContext.resources
                                     .getString(R.string.nc_notification_channel_calls_description), true,
                                     .getString(R.string.nc_notification_channel_calls_description), true,
-                                    NotificationManagerCompat.IMPORTANCE_HIGH, soundUri!!, audioAttributesBuilder.build())
+                                    NotificationManagerCompat.IMPORTANCE_HIGH, soundUri, audioAttributesBuilder.build(), NotificationUtils.getVibrationEffectForCalls(), false)
 
 
                             val uri = Uri.parse(signatureVerification!!.userEntity.baseUrl)
                             val uri = Uri.parse(signatureVerification!!.userEntity.baseUrl)
                             val baseUrl = uri.host
                             val baseUrl = uri.host
 
 
-                            val notificationBuilder = NotificationCompat.Builder(this@MagicFirebaseMessagingService, NOTIFICATION_CHANNEL_CALLS_V3)
-                                    .setPriority(NotificationCompat.PRIORITY_MAX)
+                            val notification = NotificationCompat.Builder(this@MagicFirebaseMessagingService, notificationChannelId)
+                                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                                     .setCategory(NotificationCompat.CATEGORY_CALL)
                                     .setCategory(NotificationCompat.CATEGORY_CALL)
                                     .setSmallIcon(R.drawable.ic_call_black_24dp)
                                     .setSmallIcon(R.drawable.ic_call_black_24dp)
                                     .setSubText(baseUrl)
                                     .setSubText(baseUrl)
@@ -156,10 +210,16 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
                                     .setContentTitle(EmojiCompat.get().process(decryptedPushMessage!!.subject))
                                     .setContentTitle(EmojiCompat.get().process(decryptedPushMessage!!.subject))
                                     .setAutoCancel(true)
                                     .setAutoCancel(true)
                                     .setOngoing(true)
                                     .setOngoing(true)
-                                    .setTimeoutAfter(45000L)
+                                    //.setTimeoutAfter(45000L)
+                                    .setContentIntent(fullScreenPendingIntent)
                                     .setFullScreenIntent(fullScreenPendingIntent, true)
                                     .setFullScreenIntent(fullScreenPendingIntent, true)
                                     .setSound(soundUri)
                                     .setSound(soundUri)
-                            startForeground(System.currentTimeMillis().toInt(), notificationBuilder.build())
+                                    .setVibrate(NotificationUtils.getVibrationEffectForCalls())
+                                    .build()
+                            notification.flags = notification.flags or Notification.FLAG_INSISTENT
+                            isServiceInForeground = true
+                            checkIfCallIsActive(signatureVerification!!, decryptedPushMessage!!)
+                            startForeground(decryptedPushMessage!!.timestamp.toInt(), notification)
                         } else {
                         } else {
                             val messageData = Data.Builder()
                             val messageData = Data.Builder()
                                     .putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, subject)
                                     .putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, subject)
@@ -180,6 +240,45 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
         } catch (exception: Exception) {
         } catch (exception: Exception) {
             Log.d(NotificationWorker.TAG, "Something went very wrong " + exception.localizedMessage)
             Log.d(NotificationWorker.TAG, "Something went very wrong " + exception.localizedMessage)
         }
         }
+    }
+
+    private fun checkIfCallIsActive(signatureVerification: SignatureVerification, decryptedPushMessage: DecryptedPushMessage) {
+        val ncApi = retrofit!!.newBuilder().client(okHttpClient!!.newBuilder().cookieJar(JavaNetCookieJar(CookieManager())).build()).build().create(NcApi::class.java)
+        var hasParticipantsInCall = false
+        var inCallOnDifferentDevice = false
+
+        ncApi.getPeersForCall(ApiUtils.getCredentials(signatureVerification.userEntity.username, signatureVerification.userEntity.token),
+                ApiUtils.getUrlForParticipants(signatureVerification.userEntity.baseUrl,
+                        decryptedPushMessage.id))
+                .subscribeOn(Schedulers.io())
+                .subscribe(object : Observer<ParticipantsOverall> {
+                    override fun onSubscribe(d: Disposable) {
+                    }
+
+                    override fun onNext(participantsOverall: ParticipantsOverall) {
+                        val participantList: List<Participant> = participantsOverall.ocs.data
+                        for (participant in participantList) {
+                            if (participant.participantFlags != Participant.ParticipantFlags.NOT_IN_CALL) {
+                                hasParticipantsInCall = true
+                                if (participant.userId == signatureVerification.userEntity.userId) {
+                                    inCallOnDifferentDevice = true
+                                    break
+                                }
+                            }
+                        }
+
+                        if (!hasParticipantsInCall || inCallOnDifferentDevice) {
+                            stopForeground(true)
+                        } else if (isServiceInForeground) {
+                            checkIfCallIsActive(signatureVerification, decryptedPushMessage)
+                        }
+                    }
+
+                    override fun onError(e: Throwable) {}
+                    override fun onComplete() {
+                    }
+                })
 
 
     }
     }
+
 }
 }

+ 2 - 0
app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java

@@ -61,6 +61,7 @@ import com.nextcloud.talk.R;
 import com.nextcloud.talk.api.NcApi;
 import com.nextcloud.talk.api.NcApi;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.controllers.base.BaseController;
 import com.nextcloud.talk.controllers.base.BaseController;
+import com.nextcloud.talk.events.CallNotificationClick;
 import com.nextcloud.talk.events.ConfigurationChangeEvent;
 import com.nextcloud.talk.events.ConfigurationChangeEvent;
 import com.nextcloud.talk.models.RingtoneSettings;
 import com.nextcloud.talk.models.RingtoneSettings;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.database.UserEntity;
@@ -145,6 +146,7 @@ public class CallNotificationController extends BaseController {
         super(args);
         super(args);
         NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
         NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
 
 
+        eventBus.post(new CallNotificationClick());
         this.roomId = args.getString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), "");
         this.roomId = args.getString(BundleKeys.INSTANCE.getKEY_ROOM_ID(), "");
         this.currentConversation = Parcels.unwrap(args.getParcelable(BundleKeys.INSTANCE.getKEY_ROOM()));
         this.currentConversation = Parcels.unwrap(args.getParcelable(BundleKeys.INSTANCE.getKEY_ROOM()));
         this.userBeingCalled = args.getParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY());
         this.userBeingCalled = args.getParcelable(BundleKeys.INSTANCE.getKEY_USER_ENTITY());

+ 25 - 0
app/src/main/java/com/nextcloud/talk/events/CallNotificationClick.kt

@@ -0,0 +1,25 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Mario Danic
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.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, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.events
+
+class CallNotificationClick {
+
+}

+ 1 - 1
app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java

@@ -369,7 +369,7 @@ public class NotificationWorker extends Worker {
                         NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_MESSAGES_V3(), context.getResources()
                         NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_MESSAGES_V3(), context.getResources()
                                 .getString(R.string.nc_notification_channel_messages), context.getResources()
                                 .getString(R.string.nc_notification_channel_messages), context.getResources()
                                 .getString(R.string.nc_notification_channel_messages), true,
                                 .getString(R.string.nc_notification_channel_messages), true,
-                        NotificationManager.IMPORTANCE_HIGH, soundUri, audioAttributesBuilder.build());
+                        NotificationManager.IMPORTANCE_HIGH, soundUri, audioAttributesBuilder.build(), null, false);
 
 
                 notificationBuilder.setChannelId(NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_MESSAGES_V3());
                 notificationBuilder.setChannelId(NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_MESSAGES_V3());
             } else {
             } else {

+ 14 - 15
app/src/main/java/com/nextcloud/talk/receivers/PackageReplacedReceiver.kt

@@ -57,26 +57,25 @@ class PackageReplacedReceiver : BroadcastReceiver() {
                     val notificationManager = context.getSystemService(Context
                     val notificationManager = context.getSystemService(Context
                             .NOTIFICATION_SERVICE) as NotificationManager
                             .NOTIFICATION_SERVICE) as NotificationManager
 
 
-                    if (notificationManager != null) {
-                        if (!appPreferences!!.isNotificationChannelUpgradedToV2) {
-                            for (notificationChannelGroup in notificationManager
-                                    .notificationChannelGroups) {
-                                notificationManager.deleteNotificationChannelGroup(notificationChannelGroup.id)
-                            }
+                    if (!appPreferences.isNotificationChannelUpgradedToV2) {
+                        for (notificationChannelGroup in notificationManager
+                                .notificationChannelGroups) {
+                            notificationManager.deleteNotificationChannelGroup(notificationChannelGroup.id)
+                        }
 
 
-                            notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_CALLS)
-                            notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES)
+                        notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_CALLS)
+                        notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES)
 
 
-                            appPreferences!!.setNotificationChannelIsUpgradedToV2(true)
-                        }
+                        appPreferences.setNotificationChannelIsUpgradedToV2(true)
+                    }
 
 
-                        if (!appPreferences!!.isNotificationChannelUpgradedToV3 && packageInfo.versionCode > 51) {
-                            notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES_V2)
-                            notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V2)
-                            appPreferences!!.setNotificationChannelIsUpgradedToV3(true)
-                        }
+                    if (!appPreferences.isNotificationChannelUpgradedToV3 && packageInfo.versionCode > 51) {
+                        notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES_V2)
+                        notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V2)
+                        appPreferences.setNotificationChannelIsUpgradedToV3(true)
                     }
                     }
 
 
+                    notificationManager.deleteNotificationChannel(NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V3)
                 }
                 }
             } catch (e: PackageManager.NameNotFoundException) {
             } catch (e: PackageManager.NameNotFoundException) {
                 Log.e(TAG, "Failed to fetch package info")
                 Log.e(TAG, "Failed to fetch package info")

+ 22 - 4
app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt

@@ -33,6 +33,7 @@ import android.service.notification.StatusBarNotification
 import com.nextcloud.talk.R
 import com.nextcloud.talk.R
 import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.utils.bundle.BundleKeys
 import com.nextcloud.talk.utils.bundle.BundleKeys
+import java.util.*
 
 
 object NotificationUtils {
 object NotificationUtils {
     val NOTIFICATION_CHANNEL_CALLS = "NOTIFICATION_CHANNEL_CALLS"
     val NOTIFICATION_CHANNEL_CALLS = "NOTIFICATION_CHANNEL_CALLS"
@@ -42,15 +43,26 @@ object NotificationUtils {
     val NOTIFICATION_CHANNEL_MESSAGES_V3 = "NOTIFICATION_CHANNEL_MESSAGES_V3"
     val NOTIFICATION_CHANNEL_MESSAGES_V3 = "NOTIFICATION_CHANNEL_MESSAGES_V3"
     val NOTIFICATION_CHANNEL_CALLS_V3 = "NOTIFICATION_CHANNEL_CALLS_V3"
     val NOTIFICATION_CHANNEL_CALLS_V3 = "NOTIFICATION_CHANNEL_CALLS_V3"
 
 
+    fun getVibrationEffectForCalls(): LongArray? {
+        return longArrayOf(0L, 400L, 800L, 600L, 800L, 800L, 800L, 1000L)
+    }
+
+    fun getNotificationChannelId(channelName: String,
+                                 channelDescription: String, enableLights: Boolean,
+                                 importance: Int, sound: Uri, audioAttributes: AudioAttributes, vibrationPattern: LongArray?, bypassDnd: Boolean): String {
+        return Objects.hash(channelName, channelDescription, enableLights, importance, sound, audioAttributes, vibrationPattern, bypassDnd).toString()
+    }
+
     @TargetApi(Build.VERSION_CODES.O)
     @TargetApi(Build.VERSION_CODES.O)
     fun createNotificationChannel(context: Context,
     fun createNotificationChannel(context: Context,
                                   channelId: String, channelName: String,
                                   channelId: String, channelName: String,
                                   channelDescription: String, enableLights: Boolean,
                                   channelDescription: String, enableLights: Boolean,
-                                  importance: Int, sound: Uri, audioAttributes: AudioAttributes) {
+                                  importance: Int, sound: Uri, audioAttributes: AudioAttributes,
+                                  vibrationPattern: LongArray?, bypassDnd: Boolean = false) {
 
 
         val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
         val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
 
 
-        if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O && notificationManager.getNotificationChannel(channelId) == null) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && notificationManager.getNotificationChannel(channelId) == null) {
 
 
             val channel = NotificationChannel(channelId, channelName,
             val channel = NotificationChannel(channelId, channelName,
                     importance)
                     importance)
@@ -59,7 +71,13 @@ object NotificationUtils {
             channel.enableLights(enableLights)
             channel.enableLights(enableLights)
             channel.lightColor = R.color.colorPrimary
             channel.lightColor = R.color.colorPrimary
             channel.setSound(sound, audioAttributes)
             channel.setSound(sound, audioAttributes)
-            channel.shouldVibrate()
+            if (vibrationPattern != null) {
+                channel.enableVibration(true)
+                channel.vibrationPattern = vibrationPattern
+            } else {
+                channel.enableVibration(false)
+            }
+            channel.setBypassDnd(bypassDnd)
 
 
             notificationManager.createNotificationChannel(channel)
             notificationManager.createNotificationChannel(channel)
         }
         }
@@ -68,7 +86,7 @@ object NotificationUtils {
     @TargetApi(Build.VERSION_CODES.O)
     @TargetApi(Build.VERSION_CODES.O)
     fun createNotificationChannelGroup(context: Context,
     fun createNotificationChannelGroup(context: Context,
                                        groupId: String, groupName: CharSequence) {
                                        groupId: String, groupName: CharSequence) {
-        if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
             val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
 
 
             val notificationChannelGroup = NotificationChannelGroup(groupId, groupName)
             val notificationChannelGroup = NotificationChannelGroup(groupId, groupName)