Merge "New MobileDataEnabledFlow" into main
This commit is contained in:
@@ -31,9 +31,10 @@ import androidx.preference.Preference
|
||||
import com.android.settings.R
|
||||
import com.android.settings.datausage.lib.BillingCycleRepository
|
||||
import com.android.settings.datausage.lib.NetworkUsageData
|
||||
import com.android.settings.network.MobileDataEnabledListener
|
||||
import com.android.settings.network.MobileNetworkRepository
|
||||
import com.android.settings.network.mobileDataEnabledFlow
|
||||
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
import com.android.settingslib.utils.ThreadUtils
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
@@ -43,10 +44,7 @@ import kotlin.jvm.optionals.getOrNull
|
||||
* to inspect based on usage cycle and control through [NetworkPolicy].
|
||||
*/
|
||||
@OpenForTesting
|
||||
open class DataUsageList : DataUsageBaseFragment(), MobileDataEnabledListener.Client {
|
||||
@VisibleForTesting
|
||||
lateinit var dataStateListener: MobileDataEnabledListener
|
||||
|
||||
open class DataUsageList : DataUsageBaseFragment() {
|
||||
@JvmField
|
||||
@VisibleForTesting
|
||||
var template: NetworkTemplate? = null
|
||||
@@ -89,7 +87,6 @@ open class DataUsageList : DataUsageBaseFragment(), MobileDataEnabledListener.Cl
|
||||
return
|
||||
}
|
||||
updateSubscriptionInfoEntity()
|
||||
dataStateListener = MobileDataEnabledListener(activity, this)
|
||||
dataUsageListAppsController = use(DataUsageListAppsController::class.java).apply {
|
||||
init(template)
|
||||
}
|
||||
@@ -103,6 +100,9 @@ open class DataUsageList : DataUsageBaseFragment(), MobileDataEnabledListener.Cl
|
||||
override fun onViewCreated(v: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(v, savedInstanceState)
|
||||
|
||||
requireContext().mobileDataEnabledFlow(subId)
|
||||
.collectLatestWithLifecycle(viewLifecycleOwner) { updatePolicy() }
|
||||
|
||||
val template = template ?: return
|
||||
dataUsageListHeaderController = DataUsageListHeaderController(
|
||||
setPinnedHeaderView(R.layout.apps_filter_spinner),
|
||||
@@ -114,17 +114,6 @@ open class DataUsageList : DataUsageBaseFragment(), MobileDataEnabledListener.Cl
|
||||
)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
dataStateListener.start(subId)
|
||||
updatePolicy()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
dataStateListener.stop()
|
||||
}
|
||||
|
||||
override fun getPreferenceScreenResId() = R.xml.data_usage_list
|
||||
|
||||
override fun getLogTag() = TAG
|
||||
@@ -154,13 +143,6 @@ open class DataUsageList : DataUsageBaseFragment(), MobileDataEnabledListener.Cl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of `MobileDataEnabledListener.Client`
|
||||
*/
|
||||
override fun onMobileDataEnabledChange() {
|
||||
updatePolicy()
|
||||
}
|
||||
|
||||
/** Update chart sweeps and cycle list to reflect [NetworkPolicy] for current [template]. */
|
||||
@VisibleForTesting
|
||||
fun updatePolicy() {
|
||||
|
43
src/com/android/settings/network/MobileDataEnabledFlow.kt
Normal file
43
src/com/android/settings/network/MobileDataEnabledFlow.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.network
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.Settings
|
||||
import android.telephony.SubscriptionManager
|
||||
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalChangeFlow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.merge
|
||||
|
||||
/**
|
||||
* Flow for mobile data enabled changed event.
|
||||
*
|
||||
* Note: This flow can only notify enabled status changes, cannot provide the latest status.
|
||||
*/
|
||||
fun Context.mobileDataEnabledFlow(subId: Int): Flow<Unit> {
|
||||
val flow = settingsGlobalChangeFlow(Settings.Global.MOBILE_DATA)
|
||||
return when (subId) {
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID -> flow
|
||||
else -> {
|
||||
val subIdFlow = settingsGlobalChangeFlow(
|
||||
name = Settings.Global.MOBILE_DATA + subId,
|
||||
sendInitialValue = false,
|
||||
)
|
||||
merge(flow, subIdFlow)
|
||||
}
|
||||
}
|
||||
}
|
@@ -20,7 +20,12 @@ import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
|
||||
/** Helper class to listen for changes in the enabled state of mobile data. */
|
||||
/**
|
||||
* Helper class to listen for changes in the enabled state of mobile data.
|
||||
*
|
||||
* @deprecated use {@link MobileDataEnabledFlowKt} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public class MobileDataEnabledListener {
|
||||
private Context mContext;
|
||||
private Client mClient;
|
||||
|
@@ -28,15 +28,16 @@ import com.android.settings.SettingsPreferenceFragment
|
||||
import com.android.settings.dashboard.DashboardFragment
|
||||
import com.android.settings.network.telephony.MobileNetworkUtils
|
||||
import com.android.settings.search.BaseSearchIndexProvider
|
||||
import com.android.settings.utils.observeSettingsGlobalBoolean
|
||||
import com.android.settingslib.search.SearchIndexable
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBooleanFlow
|
||||
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL and SearchIndexable.ARC.inv())
|
||||
class MobileNetworkListFragment : DashboardFragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
observeAirplaneModeAndFinishIfOn()
|
||||
collectAirplaneModeAndFinishIfOn()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -59,11 +60,9 @@ class MobileNetworkListFragment : DashboardFragment() {
|
||||
private const val KEY_ADD_SIM = "add_sim"
|
||||
|
||||
@JvmStatic
|
||||
fun SettingsPreferenceFragment.observeAirplaneModeAndFinishIfOn() {
|
||||
requireContext().observeSettingsGlobalBoolean(
|
||||
name = Settings.Global.AIRPLANE_MODE_ON,
|
||||
lifecycle = viewLifecycleOwner.lifecycle,
|
||||
) { isAirplaneModeOn: Boolean ->
|
||||
fun SettingsPreferenceFragment.collectAirplaneModeAndFinishIfOn() {
|
||||
requireContext().settingsGlobalBooleanFlow(Settings.Global.AIRPLANE_MODE_ON)
|
||||
.collectLatestWithLifecycle(viewLifecycleOwner) { isAirplaneModeOn ->
|
||||
if (isAirplaneModeOn) {
|
||||
finish()
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import static com.android.settings.network.MobileNetworkListFragment.observeAirplaneModeAndFinishIfOn;
|
||||
import static com.android.settings.network.MobileNetworkListFragment.collectAirplaneModeAndFinishIfOn;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.settings.SettingsEnums;
|
||||
@@ -334,7 +334,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
observeAirplaneModeAndFinishIfOn(this);
|
||||
collectAirplaneModeAndFinishIfOn(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.utils
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.database.ContentObserver
|
||||
import android.os.Handler
|
||||
import android.provider.Settings
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
fun Context.observeSettingsGlobalBoolean(
|
||||
name: String,
|
||||
lifecycle: Lifecycle,
|
||||
onChange: (newValue: Boolean) -> Unit,
|
||||
) {
|
||||
val field by settingsGlobalBoolean(name)
|
||||
val contentObserver = object : ContentObserver(Handler.getMain()) {
|
||||
override fun onChange(selfChange: Boolean) {
|
||||
onChange(field)
|
||||
}
|
||||
}
|
||||
val uri = Settings.Global.getUriFor(name)
|
||||
lifecycle.addObserver(object : DefaultLifecycleObserver {
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
contentResolver.registerContentObserver(uri, false, contentObserver)
|
||||
onChange(field)
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
contentResolver.unregisterContentObserver(contentObserver)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun Context.settingsGlobalBoolean(name: String): ReadWriteProperty<Any?, Boolean> =
|
||||
SettingsGlobalBooleanDelegate(this, name)
|
||||
|
||||
private class SettingsGlobalBooleanDelegate(context: Context, private val name: String) :
|
||||
ReadWriteProperty<Any?, Boolean> {
|
||||
|
||||
private val contentResolver: ContentResolver = context.contentResolver
|
||||
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean =
|
||||
Settings.Global.getInt(contentResolver, name, 0) != 0
|
||||
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
|
||||
Settings.Global.putInt(contentResolver, name, if (value) 1 else 0)
|
||||
}
|
||||
}
|
@@ -23,22 +23,18 @@ import android.os.Bundle
|
||||
import android.os.UserManager
|
||||
import android.provider.Settings
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.settings.datausage.DataUsageListTest.ShadowDataUsageBaseFragment
|
||||
import com.android.settings.datausage.TemplatePreference.NetworkServices
|
||||
import com.android.settings.datausage.lib.BillingCycleRepository
|
||||
import com.android.settings.network.MobileDataEnabledListener
|
||||
import com.android.settings.testutils.FakeFeatureFactory
|
||||
import com.android.settingslib.NetworkPolicyEditor
|
||||
import com.android.settingslib.core.AbstractPreferenceController
|
||||
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.doNothing
|
||||
import org.mockito.Mockito.doReturn
|
||||
@@ -61,9 +57,6 @@ class DataUsageListTest {
|
||||
@get:Rule
|
||||
val mockito: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
@Mock
|
||||
private lateinit var mobileDataEnabledListener: MobileDataEnabledListener
|
||||
|
||||
@Mock
|
||||
private lateinit var networkServices: NetworkServices
|
||||
|
||||
@@ -86,7 +79,6 @@ class DataUsageListTest {
|
||||
fun setUp() {
|
||||
FakeFeatureFactory.setupForTest()
|
||||
networkServices.mPolicyEditor = mock(NetworkPolicyEditor::class.java)
|
||||
dataUsageList.dataStateListener = mobileDataEnabledListener
|
||||
doReturn(context).`when`(dataUsageList).context
|
||||
doReturn(userManager).`when`(context).getSystemService(UserManager::class.java)
|
||||
doReturn(false).`when`(userManager).isGuestUser
|
||||
@@ -112,46 +104,6 @@ class DataUsageListTest {
|
||||
verify(dataUsageList).finish()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun resume_shouldListenDataStateChange() {
|
||||
dataUsageList.template = mock(NetworkTemplate::class.java)
|
||||
dataUsageList.onCreate(null)
|
||||
dataUsageList.dataStateListener = mobileDataEnabledListener
|
||||
ReflectionHelpers.setField(
|
||||
dataUsageList,
|
||||
"mVisibilityLoggerMixin",
|
||||
mock(VisibilityLoggerMixin::class.java),
|
||||
)
|
||||
ReflectionHelpers.setField(
|
||||
dataUsageList,
|
||||
"mPreferenceManager",
|
||||
mock(PreferenceManager::class.java),
|
||||
)
|
||||
dataUsageList.onResume()
|
||||
verify(mobileDataEnabledListener).start(ArgumentMatchers.anyInt())
|
||||
dataUsageList.onPause()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pause_shouldUnlistenDataStateChange() {
|
||||
dataUsageList.template = mock(NetworkTemplate::class.java)
|
||||
dataUsageList.onCreate(null)
|
||||
dataUsageList.dataStateListener = mobileDataEnabledListener
|
||||
ReflectionHelpers.setField(
|
||||
dataUsageList, "mVisibilityLoggerMixin", mock(
|
||||
VisibilityLoggerMixin::class.java
|
||||
)
|
||||
)
|
||||
ReflectionHelpers.setField(
|
||||
dataUsageList, "mPreferenceManager", mock(
|
||||
PreferenceManager::class.java
|
||||
)
|
||||
)
|
||||
dataUsageList.onResume()
|
||||
dataUsageList.onPause()
|
||||
verify(mobileDataEnabledListener).stop()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun processArgument_shouldGetTemplateFromArgument() {
|
||||
val args = Bundle()
|
||||
|
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.network
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.Settings
|
||||
import android.telephony.SubscriptionManager
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
|
||||
import com.android.settingslib.spa.testutils.toListWithTimeout
|
||||
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBoolean
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MobileDataEnabledFlowTest {
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
@Test
|
||||
fun mobileDataEnabledFlow_notified(): Unit = runBlocking {
|
||||
val flow = context.mobileDataEnabledFlow(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
|
||||
|
||||
assertThat(flow.firstWithTimeoutOrNull()).isNotNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mobileDataEnabledFlow_changed_notified(): Unit = runBlocking {
|
||||
var mobileDataEnabled by context.settingsGlobalBoolean(Settings.Global.MOBILE_DATA)
|
||||
mobileDataEnabled = false
|
||||
|
||||
val flow = context.mobileDataEnabledFlow(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
|
||||
mobileDataEnabled = true
|
||||
|
||||
assertThat(flow.firstWithTimeoutOrNull()).isNotNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mobileDataEnabledFlow_forSubIdNotChanged(): Unit = runBlocking {
|
||||
var mobileDataEnabled by context.settingsGlobalBoolean(Settings.Global.MOBILE_DATA)
|
||||
mobileDataEnabled = false
|
||||
var mobileDataEnabledForSubId
|
||||
by context.settingsGlobalBoolean(Settings.Global.MOBILE_DATA + SUB_ID)
|
||||
mobileDataEnabledForSubId = false
|
||||
|
||||
val listDeferred = async {
|
||||
context.mobileDataEnabledFlow(SUB_ID).toListWithTimeout()
|
||||
}
|
||||
|
||||
assertThat(listDeferred.await()).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mobileDataEnabledFlow_forSubIdChanged(): Unit = runBlocking {
|
||||
var mobileDataEnabled by context.settingsGlobalBoolean(Settings.Global.MOBILE_DATA)
|
||||
mobileDataEnabled = false
|
||||
var mobileDataEnabledForSubId
|
||||
by context.settingsGlobalBoolean(Settings.Global.MOBILE_DATA + SUB_ID)
|
||||
mobileDataEnabledForSubId = false
|
||||
|
||||
val listDeferred = async {
|
||||
context.mobileDataEnabledFlow(SUB_ID).toListWithTimeout()
|
||||
}
|
||||
delay(100)
|
||||
mobileDataEnabledForSubId = true
|
||||
|
||||
assertThat(listDeferred.await()).hasSize(2)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val SUB_ID = 123
|
||||
}
|
||||
}
|
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.Settings
|
||||
import androidx.lifecycle.testing.TestLifecycleOwner
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SettingsGlobalBooleanDelegateTest {
|
||||
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
@Test
|
||||
fun getValue_setTrue_returnTrue() {
|
||||
Settings.Global.putInt(context.contentResolver, TEST_NAME, 1)
|
||||
|
||||
val value by context.settingsGlobalBoolean(TEST_NAME)
|
||||
|
||||
assertThat(value).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getValue_setFalse_returnFalse() {
|
||||
Settings.Global.putInt(context.contentResolver, TEST_NAME, 0)
|
||||
|
||||
val value by context.settingsGlobalBoolean(TEST_NAME)
|
||||
|
||||
assertThat(value).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setValue_setTrue_returnTrue() {
|
||||
var value by context.settingsGlobalBoolean(TEST_NAME)
|
||||
|
||||
value = true
|
||||
|
||||
assertThat(Settings.Global.getInt(context.contentResolver, TEST_NAME, 0)).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setValue_setFalse_returnFalse() {
|
||||
var value by context.settingsGlobalBoolean(TEST_NAME)
|
||||
|
||||
value = false
|
||||
|
||||
assertThat(Settings.Global.getInt(context.contentResolver, TEST_NAME, 1)).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun observeSettingsGlobalBoolean_valueNotChanged() {
|
||||
var value by context.settingsGlobalBoolean(TEST_NAME)
|
||||
value = false
|
||||
var newValue: Boolean? = null
|
||||
|
||||
context.observeSettingsGlobalBoolean(TEST_NAME, TestLifecycleOwner().lifecycle) {
|
||||
newValue = it
|
||||
}
|
||||
|
||||
assertThat(newValue).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun observeSettingsGlobalBoolean_valueChanged() {
|
||||
var value by context.settingsGlobalBoolean(TEST_NAME)
|
||||
value = false
|
||||
var newValue: Boolean? = null
|
||||
|
||||
context.observeSettingsGlobalBoolean(TEST_NAME, TestLifecycleOwner().lifecycle) {
|
||||
newValue = it
|
||||
}
|
||||
value = true
|
||||
|
||||
assertThat(newValue).isFalse()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TEST_NAME = "test_boolean_delegate"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user