diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt index 53877bf80b..15fa601abb 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/internal/OneSignalImp.kt @@ -323,12 +323,6 @@ internal class OneSignalImp : IOneSignal, IServiceProvider { } } else { Logging.debug("initWithContext: using cached user ${identityModelStore!!.model.onesignalId}") - operationRepo!!.enqueue( - RefreshUserOperation( - configModel!!.appId, - identityModelStore!!.model.onesignalId, - ), - ) } startupService!!.start() diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/UserModule.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/UserModule.kt index 996b37178f..f371e6d391 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/UserModule.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/UserModule.kt @@ -4,6 +4,7 @@ import com.onesignal.common.modules.IModule import com.onesignal.common.services.ServiceBuilder import com.onesignal.core.internal.operations.IOperationExecutor import com.onesignal.core.internal.startup.IBootstrapService +import com.onesignal.core.internal.startup.IStartableService import com.onesignal.user.internal.UserManager import com.onesignal.user.internal.backend.IIdentityBackendService import com.onesignal.user.internal.backend.ISubscriptionBackendService @@ -24,6 +25,7 @@ import com.onesignal.user.internal.operations.impl.listeners.IdentityModelStoreL import com.onesignal.user.internal.operations.impl.listeners.PropertiesModelStoreListener import com.onesignal.user.internal.operations.impl.listeners.SubscriptionModelStoreListener import com.onesignal.user.internal.properties.PropertiesModelStore +import com.onesignal.user.internal.service.UserRefreshService import com.onesignal.user.internal.subscriptions.ISubscriptionManager import com.onesignal.user.internal.subscriptions.SubscriptionModelStore import com.onesignal.user.internal.subscriptions.impl.SubscriptionManager @@ -61,5 +63,7 @@ internal class UserModule : IModule { builder.register().provides() builder.register().provides() builder.register().provides() + + builder.register().provides() } } diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/service/UserRefreshService.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/service/UserRefreshService.kt new file mode 100644 index 0000000000..b2371d3214 --- /dev/null +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/service/UserRefreshService.kt @@ -0,0 +1,49 @@ +package com.onesignal.user.internal.service + +import com.onesignal.core.internal.application.IApplicationLifecycleHandler +import com.onesignal.core.internal.application.IApplicationService +import com.onesignal.core.internal.config.ConfigModelStore +import com.onesignal.core.internal.operations.IOperationRepo +import com.onesignal.core.internal.startup.IStartableService +import com.onesignal.user.internal.identity.IdentityModelStore +import com.onesignal.user.internal.operations.RefreshUserOperation + +// Ensure cache for the user is refreshed once per cold start when app +// is in the foreground. This saves resources as there are a number of +// events (such as push received or non-OneSignal events) that start +// the app in the background but will never read/write any user +// properties. +class UserRefreshService( + private val _applicationService: IApplicationService, + private val _operationRepo: IOperationRepo, + private val _configModelStore: ConfigModelStore, + private val _identityModelStore: IdentityModelStore, +) : IStartableService, + IApplicationLifecycleHandler { + private fun refreshUser() { + _operationRepo.enqueue( + RefreshUserOperation( + _configModelStore.model.appId, + _identityModelStore.model.onesignalId, + ), + ) + } + + override fun start() { + if (_applicationService.isInForeground) { + refreshUser() + } else { + _applicationService.addApplicationLifecycleHandler(this) + } + } + + private var onFocusCalled: Boolean = false + + override fun onFocus() { + if (onFocusCalled) return + onFocusCalled = true + refreshUser() + } + + override fun onUnfocused() { } +} diff --git a/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/InAppMessagesManager.kt b/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/InAppMessagesManager.kt index 2f1f46d88d..978fb6ab2a 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/InAppMessagesManager.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/main/java/com/onesignal/inAppMessages/internal/InAppMessagesManager.kt @@ -9,6 +9,7 @@ import com.onesignal.common.exceptions.BackendException import com.onesignal.common.modeling.ISingletonModelStoreChangeHandler import com.onesignal.common.modeling.ModelChangedArgs import com.onesignal.common.threading.suspendifyOnThread +import com.onesignal.core.internal.application.IApplicationLifecycleHandler import com.onesignal.core.internal.application.IApplicationService import com.onesignal.core.internal.config.ConfigModel import com.onesignal.core.internal.config.ConfigModelStore @@ -71,7 +72,8 @@ internal class InAppMessagesManager( ISingletonModelStoreChangeHandler, IInAppLifecycleEventHandler, ITriggerHandler, - ISessionLifecycleHandler { + ISessionLifecycleHandler, + IApplicationLifecycleHandler { private val lifecycleCallback = EventProducer() private val messageClickCallback = EventProducer() @@ -133,6 +135,7 @@ internal class InAppMessagesManager( _lifecycle.subscribe(this) _triggerController.subscribe(this) _sessionService.subscribe(this) + _applicationService.addApplicationLifecycleHandler(this) suspendifyOnThread { _repository.cleanCachedInAppMessages() @@ -225,6 +228,14 @@ internal class InAppMessagesManager( // called when a new push subscription is added, or the app id is updated, or a new session starts private suspend fun fetchMessages() { + // We only want to fetch IAMs if we know the app is in the + // foreground, as we don't want to do this for background + // events (such as push received), wasting resources for + // IAMs that are never shown. + if (!_applicationService.isInForeground) { + return + } + val appId = _configModelStore.model.appId val subscriptionId = _subscriptionManager.subscriptions.push.id @@ -869,4 +880,16 @@ internal class InAppMessagesManager( .setPositiveButton(android.R.string.ok) { _, _ -> suspendifyOnThread { showMultiplePrompts(inAppMessage, prompts) } } .show() } + + private var onFocusCalled: Boolean = false + + override fun onFocus() { + if (onFocusCalled) return + onFocusCalled = true + suspendifyOnThread { + fetchMessages() + } + } + + override fun onUnfocused() { } }