Avoid using the Activity, and use eventSink instead of lambda in states.
This commit is contained in:
@@ -7,13 +7,13 @@
|
||||
|
||||
package io.element.android.features.roomlist.impl.components
|
||||
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import io.element.android.libraries.designsystem.components.Announcement
|
||||
import io.element.android.libraries.designsystem.components.AnnouncementType
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.push.api.battery.BatteryOptimizationEvents
|
||||
import io.element.android.libraries.push.api.battery.BatteryOptimizationState
|
||||
import io.element.android.libraries.push.api.battery.aBatteryOptimizationState
|
||||
|
||||
@@ -22,7 +22,6 @@ internal fun BatteryOptimizationBanner(
|
||||
state: BatteryOptimizationState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val activity = LocalActivity.current
|
||||
Announcement(
|
||||
modifier = modifier.roomListBannerPadding(),
|
||||
// TODO Localazy
|
||||
@@ -30,8 +29,8 @@ internal fun BatteryOptimizationBanner(
|
||||
description = "To be sure to receive all the notifications, it can help to disable the battery optimization for this application.",
|
||||
type = AnnouncementType.Actionable(
|
||||
actionText = "Yes, disable",
|
||||
onActionClick = { state.openSettings(activity) },
|
||||
onDismissClick = state.dismiss,
|
||||
onActionClick = { state.eventSink(BatteryOptimizationEvents.DoAction) },
|
||||
onDismissClick = { state.eventSink(BatteryOptimizationEvents.Dismiss) },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.push.api.battery
|
||||
|
||||
sealed interface BatteryOptimizationEvents {
|
||||
data object Dismiss : BatteryOptimizationEvents
|
||||
data object DoAction : BatteryOptimizationEvents
|
||||
}
|
||||
@@ -7,10 +7,7 @@
|
||||
|
||||
package io.element.android.libraries.push.api.battery
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
data class BatteryOptimizationState(
|
||||
val shouldDisplayBanner: Boolean,
|
||||
val dismiss: () -> Unit,
|
||||
val openSettings: (Activity?) -> Unit,
|
||||
val eventSink: (BatteryOptimizationEvents) -> Unit,
|
||||
)
|
||||
|
||||
@@ -7,14 +7,10 @@
|
||||
|
||||
package io.element.android.libraries.push.api.battery
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
fun aBatteryOptimizationState(
|
||||
shouldDisplayBanner: Boolean = false,
|
||||
dismiss: () -> Unit = {},
|
||||
openSettings: (Activity?) -> Unit = {},
|
||||
eventSink: (BatteryOptimizationEvents) -> Unit = {},
|
||||
) = BatteryOptimizationState(
|
||||
shouldDisplayBanner = shouldDisplayBanner,
|
||||
dismiss = dismiss,
|
||||
openSettings = openSettings,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
package io.element.android.libraries.push.impl.battery
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -19,6 +18,7 @@ import androidx.core.net.toUri
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.di.ApplicationContext
|
||||
import io.element.android.services.toolbox.api.intent.ExternalIntentLauncher
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -39,16 +39,16 @@ interface BatteryOptimization {
|
||||
* This will open the system settings where the user can disable battery optimizations.
|
||||
* See https://developer.android.com/training/monitoring-device-state/doze-standby#exemption-cases
|
||||
*
|
||||
* @param activity The activity from which to start the settings intent.
|
||||
* @return true if the intent was successfully started, false if the activity was not found
|
||||
*/
|
||||
fun requestDisablingBatteryOptimization(activity: Activity?): Boolean
|
||||
fun requestDisablingBatteryOptimization(): Boolean
|
||||
}
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class AndroidBatteryOptimization @Inject constructor(
|
||||
@ApplicationContext
|
||||
private val context: Context,
|
||||
private val externalIntentLauncher: ExternalIntentLauncher,
|
||||
) : BatteryOptimization {
|
||||
override fun isIgnoringBatteryOptimizations(): Boolean {
|
||||
return context.getSystemService<PowerManager>()
|
||||
@@ -56,13 +56,12 @@ class AndroidBatteryOptimization @Inject constructor(
|
||||
}
|
||||
|
||||
@SuppressLint("BatteryLife")
|
||||
override fun requestDisablingBatteryOptimization(activity: Activity?): Boolean {
|
||||
activity ?: return false
|
||||
override fun requestDisablingBatteryOptimization(): Boolean {
|
||||
val intent = Intent()
|
||||
intent.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||
intent.data = ("package:" + context.packageName).toUri()
|
||||
return try {
|
||||
activity.startActivity(intent)
|
||||
externalIntentLauncher.launch(intent)
|
||||
true
|
||||
} catch (exception: ActivityNotFoundException) {
|
||||
Timber.w(exception, "Cannot request ignoring battery optimizations.")
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.compose.LifecycleResumeEffect
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.push.api.battery.BatteryOptimizationEvents
|
||||
import io.element.android.libraries.push.api.battery.BatteryOptimizationState
|
||||
import io.element.android.libraries.push.impl.push.MutableBatteryOptimizationStore
|
||||
import io.element.android.libraries.push.impl.store.PushDataStore
|
||||
@@ -45,22 +46,26 @@ class BatteryOptimizationPresenter @Inject constructor(
|
||||
onPauseOrDispose {}
|
||||
}
|
||||
|
||||
return BatteryOptimizationState(
|
||||
shouldDisplayBanner = localShouldDisplayBanner && storeShouldDisplayBanner && !isSystemIgnoringBatteryOptimizations,
|
||||
dismiss = {
|
||||
coroutineScope.launch {
|
||||
fun handleEvents(event: BatteryOptimizationEvents) {
|
||||
when (event) {
|
||||
BatteryOptimizationEvents.Dismiss -> coroutineScope.launch {
|
||||
mutableBatteryOptimizationStore.onOptimizationBannerDismissed()
|
||||
}
|
||||
},
|
||||
openSettings = { activity ->
|
||||
isRequestSent = true
|
||||
if (batteryOptimization.requestDisablingBatteryOptimization(activity).not()) {
|
||||
// If not able to perform the request, ensure that we do not display the banner again
|
||||
coroutineScope.launch {
|
||||
mutableBatteryOptimizationStore.onOptimizationBannerDismissed()
|
||||
BatteryOptimizationEvents.DoAction -> {
|
||||
isRequestSent = true
|
||||
if (batteryOptimization.requestDisablingBatteryOptimization().not()) {
|
||||
// If not able to perform the request, ensure that we do not display the banner again
|
||||
coroutineScope.launch {
|
||||
mutableBatteryOptimizationStore.onOptimizationBannerDismissed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BatteryOptimizationState(
|
||||
shouldDisplayBanner = localShouldDisplayBanner && storeShouldDisplayBanner && !isSystemIgnoringBatteryOptimizations,
|
||||
eventSink = ::handleEvents,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ package io.element.android.libraries.push.impl.battery
|
||||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.push.api.battery.BatteryOptimizationEvents
|
||||
import io.element.android.libraries.push.impl.push.FakeMutableBatteryOptimizationStore
|
||||
import io.element.android.libraries.push.impl.push.MutableBatteryOptimizationStore
|
||||
import io.element.android.libraries.push.impl.store.InMemoryPushDataStore
|
||||
@@ -96,7 +97,7 @@ class BatteryOptimizationPresenterTest {
|
||||
assertThat(initialState.shouldDisplayBanner).isFalse()
|
||||
val displayedItem = awaitItem()
|
||||
assertThat(displayedItem.shouldDisplayBanner).isTrue()
|
||||
displayedItem.dismiss()
|
||||
displayedItem.eventSink(BatteryOptimizationEvents.Dismiss)
|
||||
onOptimizationBannerDismissedResult.assertions().isCalledOnce()
|
||||
}
|
||||
}
|
||||
@@ -122,7 +123,7 @@ class BatteryOptimizationPresenterTest {
|
||||
assertThat(initialState.shouldDisplayBanner).isFalse()
|
||||
val displayedItem = awaitItem()
|
||||
assertThat(displayedItem.shouldDisplayBanner).isTrue()
|
||||
displayedItem.openSettings(null)
|
||||
displayedItem.eventSink(BatteryOptimizationEvents.DoAction)
|
||||
requestDisablingBatteryOptimizationResult.assertions().isCalledOnce()
|
||||
onOptimizationBannerDismissedResult.assertions().isCalledOnce()
|
||||
}
|
||||
@@ -148,7 +149,7 @@ class BatteryOptimizationPresenterTest {
|
||||
assertThat(initialState.shouldDisplayBanner).isFalse()
|
||||
val displayedItem = awaitItem()
|
||||
assertThat(displayedItem.shouldDisplayBanner).isTrue()
|
||||
displayedItem.openSettings(null)
|
||||
displayedItem.eventSink(BatteryOptimizationEvents.DoAction)
|
||||
requestDisablingBatteryOptimizationResult.assertions().isCalledOnce()
|
||||
batteryOptimization.isIgnoringBatteryOptimizationsResult = true
|
||||
lifeCycleOwner.givenState(Lifecycle.State.RESUMED)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
package io.element.android.libraries.push.impl.battery
|
||||
|
||||
import android.app.Activity
|
||||
import io.element.android.tests.testutils.lambda.lambdaError
|
||||
|
||||
class FakeBatteryOptimization(
|
||||
@@ -18,7 +17,7 @@ class FakeBatteryOptimization(
|
||||
return isIgnoringBatteryOptimizationsResult
|
||||
}
|
||||
|
||||
override fun requestDisablingBatteryOptimization(activity: Activity?): Boolean {
|
||||
override fun requestDisablingBatteryOptimization(): Boolean {
|
||||
return requestDisablingBatteryOptimizationResult()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user