diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt index 5545595dc6..83767f90d7 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexApp.kt @@ -46,6 +46,7 @@ class SimplexApp: Application(), LifecycleEventObserver { override fun onCreate() { super.onCreate() + AppContextProvider.initialize(this) if (ProcessPhoenix.isPhoenixProcess(this)) { return } else { diff --git a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt index 90e51c7528..289ecc0a31 100644 --- a/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt +++ b/apps/multiplatform/android/src/main/java/chat/simplex/app/SimplexService.kt @@ -144,11 +144,18 @@ class SimplexService: Service() { return@withLongRunningApi } saveServiceState(self, ServiceState.STARTED) - wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).run { - newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG).apply { - acquire() - } - } +// Permanent wakelock prevents deep sleep and results in high battery usage. +// Instead, the app relies on being whitelisted for unrestricted battery usage, +// and also takes wakelock on network events and on network information changes, which allows it to reconnect. +// Network events and information changes are delivered even when device is in deep sleep. +// Possibly, we may need to additionally use "alarms" to wake the app periodically, +// but in all pre-release tests the app was reliably delivering messages in deep sleep, even restored dropped connections. +// +// wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).run { +// newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG).apply { +// acquire() +// } +// } } finally { isCheckingNewMessages = false } @@ -167,7 +174,7 @@ class SimplexService: Service() { } return null } - + private fun createServiceNotification(title: String, text: String): Notification { val pendingIntent: PendingIntent = Intent(this, MainActivity::class.java).let { notificationIntent -> PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE) diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt index 825bc8b846..77e0f49cc8 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/helpers/NetworkObserver.kt @@ -73,6 +73,7 @@ class NetworkObserver { } private fun setNetworkInfo(info: UserNetworkInfo) { + getWakeLock(timeout = 180000) Log.d(TAG, "Network changed: $info") noNetworkJob.cancel() if (info.online) { diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt index cd1672f3e9..a5e105ce93 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/AppCommon.android.kt @@ -13,7 +13,6 @@ import java.lang.ref.WeakReference import java.util.* import java.util.concurrent.Semaphore import kotlin.concurrent.thread -import kotlin.random.Random actual val appPlatform = AppPlatform.ANDROID diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/SimplexService.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/SimplexService.android.kt new file mode 100644 index 0000000000..14e4134010 --- /dev/null +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/SimplexService.android.kt @@ -0,0 +1,28 @@ +package chat.simplex.common.platform + +import android.content.Context +import android.os.PowerManager + +actual fun getWakeLock(timeout: Long): (() -> Unit) { + val context = AppContextProvider.getApplicationContext() + ?: throw IllegalStateException("Application context not initialized") + var wakeLock: PowerManager.WakeLock? = (context.applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager).run { + newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SimplexService::lock").apply { + acquire(timeout) + } + } + return { + wakeLock?.release() + wakeLock = null + } +} + +object AppContextProvider { + private var applicationContext: Context? = null + + fun initialize(context: Context) { + this.applicationContext = context.applicationContext + } + + fun getApplicationContext(): Context? = applicationContext +} diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 19a3cb264b..1b0714dd9d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -479,7 +479,7 @@ class AppPreferences { } } -private const val MESSAGE_TIMEOUT: Int = 15_000_000 +private const val MESSAGE_TIMEOUT: Int = 300_000_000 object ChatController { var ctrl: ChatCtrl? = -1 @@ -642,6 +642,7 @@ object ChatController { if (receiverStarted) return receiverStarted = true CoroutineScope(Dispatchers.IO).launch { + var releaseLock: (() -> Unit) = {} while (true) { /** Global [ctrl] can be null. It's needed for having the same [ChatModel] that already made in [ChatController] without the need * to change it everywhere in code after changing a database. @@ -652,7 +653,9 @@ object ChatController { break } try { + releaseLock() val msg = recvMsg(ctrl) + releaseLock = getWakeLock(timeout = 60000) if (msg != null) { val finishedWithoutTimeout = withTimeoutOrNull(60_000L) { processReceivedMsg(msg) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/SimplexService.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/SimplexService.kt new file mode 100644 index 0000000000..0644b5dd30 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/SimplexService.kt @@ -0,0 +1,3 @@ +package chat.simplex.common.platform + +expect fun getWakeLock(timeout: Long): (() -> Unit) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt index 59b9d596f1..2fc427cd2e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt @@ -4,10 +4,8 @@ import SectionBottomSpacer import SectionTextFooter import SectionView import SectionViewSelectable -import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.* -import androidx.compose.ui.Modifier import androidx.compose.ui.text.AnnotatedString import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.capitalize @@ -15,7 +13,6 @@ import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.style.TextOverflow import chat.simplex.common.model.* import chat.simplex.common.platform.* -import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF import chat.simplex.common.views.helpers.* import chat.simplex.res.MR import kotlin.collections.ArrayList diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/SimplexService.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/SimplexService.desktop.kt new file mode 100644 index 0000000000..a9d411916c --- /dev/null +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/SimplexService.desktop.kt @@ -0,0 +1,6 @@ +package chat.simplex.common.platform + +actual fun getWakeLock(timeout: Long): (() -> Unit) { + return {} +} +