From 05ee5794f2a411748c3a2bcfdb903a5da072b188 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 10 May 2022 15:33:20 +0200 Subject: [PATCH] Try to show foreground service notification asap to prevent crash if Core takes too long to start --- .../java/org/linphone/LinphoneApplication.kt | 12 +++++++++--- .../java/org/linphone/core/CoreContext.kt | 19 ++++++++++++++++--- .../java/org/linphone/core/CoreService.kt | 17 +++++++++-------- .../notifications/NotificationsManager.kt | 17 +++++++++++++---- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneApplication.kt b/app/src/main/java/org/linphone/LinphoneApplication.kt index b548d5da1..c1386461b 100644 --- a/app/src/main/java/org/linphone/LinphoneApplication.kt +++ b/app/src/main/java/org/linphone/LinphoneApplication.kt @@ -72,15 +72,21 @@ class LinphoneApplication : Application(), ImageLoaderFactory { Log.i("[Application] Core config & preferences created") } - fun ensureCoreExists(context: Context, pushReceived: Boolean = false) { + fun ensureCoreExists( + context: Context, + pushReceived: Boolean = false, + service: CoreService? = null, + useAutoStartDescription: Boolean = false + ): Boolean { if (::coreContext.isInitialized && !coreContext.stopped) { Log.d("[Application] Skipping Core creation (push received? $pushReceived)") - return + return false } Log.i("[Application] Core context is being created ${if (pushReceived) "from push" else ""}") - coreContext = CoreContext(context, corePreferences.config) + coreContext = CoreContext(context, corePreferences.config, service, useAutoStartDescription) coreContext.start() + return true } } diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 055926e8a..820992a18 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -64,7 +64,13 @@ import org.linphone.telecom.TelecomHelper import org.linphone.utils.* import org.linphone.utils.Event -class CoreContext(val context: Context, coreConfig: Config) : LifecycleOwner, ViewModelStoreOwner { +class CoreContext( + val context: Context, + coreConfig: Config, + service: CoreService? = null, + useAutoStartDescription: Boolean = false +) : + LifecycleOwner, ViewModelStoreOwner { private val _lifecycleRegistry = LifecycleRegistry(this) override fun getLifecycle(): Lifecycle { return _lifecycleRegistry @@ -283,6 +289,8 @@ class CoreContext(val context: Context, coreConfig: Config) : LifecycleOwner, Vi Log.i("[Context] Crashlytics enabled, register logging service listener") } + _lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED + Log.i("=========================================") Log.i("==== Linphone-android information dump ====") Log.i("VERSION=${BuildConfig.VERSION_NAME} / ${BuildConfig.VERSION_CODE}") @@ -290,9 +298,15 @@ class CoreContext(val context: Context, coreConfig: Config) : LifecycleOwner, Vi Log.i("BUILD TYPE=${BuildConfig.BUILD_TYPE}") Log.i("=========================================") + if (service != null) { + Log.i("[Context] Starting foreground service") + notificationsManager.startForeground(service, useAutoStartDescription) + } + core = Factory.instance().createCoreWithConfig(coreConfig, context) + stopped = false - _lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED + _lifecycleRegistry.currentState = Lifecycle.State.CREATED Log.i("[Context] Ready") } @@ -316,7 +330,6 @@ class CoreContext(val context: Context, coreConfig: Config) : LifecycleOwner, Vi configureCore() - _lifecycleRegistry.currentState = Lifecycle.State.CREATED core.start() _lifecycleRegistry.currentState = Lifecycle.State.STARTED diff --git a/app/src/main/java/org/linphone/core/CoreService.kt b/app/src/main/java/org/linphone/core/CoreService.kt index 4bfa33eea..70fa441b6 100644 --- a/app/src/main/java/org/linphone/core/CoreService.kt +++ b/app/src/main/java/org/linphone/core/CoreService.kt @@ -29,23 +29,24 @@ import org.linphone.core.tools.service.CoreService class CoreService : CoreService() { override fun onCreate() { super.onCreate() - - Log.i("[Service] Ensuring Core exists") - ensureCoreExists(applicationContext) - - coreContext.notificationsManager.service = this Log.i("[Service] Created") } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + Log.i("[Service] Ensuring Core exists") if (corePreferences.keepServiceAlive) { Log.i("[Service] Starting as foreground to keep app alive in background") - coreContext.notificationsManager.startForeground(this, false) + if (!ensureCoreExists(applicationContext, pushReceived = false, service = this, useAutoStartDescription = false)) { + coreContext.notificationsManager.startForeground(this, false) + } } else if (intent?.extras?.get("StartForeground") == true) { Log.i("[Service] Starting as foreground due to device boot or app update") - coreContext.notificationsManager.startForeground(this, true) + if (!ensureCoreExists(applicationContext, pushReceived = false, service = this, useAutoStartDescription = true)) { + coreContext.notificationsManager.startForeground(this, true) + } coreContext.checkIfForegroundServiceNotificationCanBeRemovedAfterDelay(5000) } + return super.onStartCommand(intent, flags, startId) } @@ -80,7 +81,7 @@ class CoreService : CoreService() { override fun onDestroy() { Log.i("[Service] Stopping") - coreContext.notificationsManager.service = null + coreContext.notificationsManager.serviceDestroyed() super.onDestroy() } diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index a6e71815a..e0f93e799 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -105,7 +105,7 @@ class NotificationsManager(private val context: Context) { private var currentForegroundServiceNotificationId: Int = 0 private var serviceNotification: Notification? = null - var service: CoreService? = null + private var service: CoreService? = null var currentlyDisplayedChatRoomAddress: String? = null @@ -330,6 +330,8 @@ class NotificationsManager(private val context: Context) { } fun startForeground(coreService: CoreService, useAutoStartDescription: Boolean = true) { + service = coreService + if (serviceNotification == null) { createServiceNotification(useAutoStartDescription) if (serviceNotification == null) { @@ -337,10 +339,10 @@ class NotificationsManager(private val context: Context) { return } } + currentForegroundServiceNotificationId = SERVICE_NOTIF_ID Log.i("[Notifications Manager] Starting service as foreground [$currentForegroundServiceNotificationId]") Compatibility.startForegroundService(coreService, currentForegroundServiceNotificationId, serviceNotification) - service = coreService } private fun startForeground(notificationId: Int, callNotification: Notification) { @@ -353,9 +355,11 @@ class NotificationsManager(private val context: Context) { fun stopForegroundNotification() { if (service != null) { - Log.i("[Notifications Manager] Stopping service as foreground [$currentForegroundServiceNotificationId]") + if (currentForegroundServiceNotificationId != 0) { + Log.i("[Notifications Manager] Stopping service as foreground [$currentForegroundServiceNotificationId]") + currentForegroundServiceNotificationId = 0 + } service?.stopForeground(true) - currentForegroundServiceNotificationId = 0 } } @@ -373,6 +377,11 @@ class NotificationsManager(private val context: Context) { } } + fun serviceDestroyed() { + stopForegroundNotification() + service = null + } + private fun createServiceNotification(useAutoStartDescription: Boolean = false) { val serviceChannel = context.getString(R.string.notification_channel_service_id) if (Compatibility.getChannelImportance(notificationManager, serviceChannel) == NotificationManagerCompat.IMPORTANCE_NONE) {