Try to show foreground service notification asap to prevent crash if Core takes too long to start

This commit is contained in:
Sylvain Berfini 2022-05-10 15:33:20 +02:00
parent 8f8949cb3e
commit 05ee5794f2
4 changed files with 47 additions and 18 deletions

View file

@ -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
}
}

View file

@ -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

View file

@ -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()
}

View file

@ -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) {