Fix DataUsagePreferenceController ANR am: d42cc8e5e2 am: eb8948e309
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/23896225 Change-Id: I3e6b70cb33a51348b9504226787de2e149af5870 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.telephony;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.app.usage.NetworkStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.DataUnit;
|
||||
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowTelephonyManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DataUsagePreferenceControllerTest {
|
||||
private static final int SUB_ID = 2;
|
||||
|
||||
@Mock
|
||||
private NetworkStatsManager mNetworkStatsManager;
|
||||
private DataUsagePreferenceController mController;
|
||||
private SwitchPreference mPreference;
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
|
||||
final ShadowTelephonyManager shadowTelephonyManager = Shadows.shadowOf(telephonyManager);
|
||||
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(SUB_ID, telephonyManager);
|
||||
shadowTelephonyManager.setTelephonyManagerForSubscriptionId(
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID, telephonyManager);
|
||||
|
||||
doReturn(mNetworkStatsManager).when(mContext).getSystemService(NetworkStatsManager.class);
|
||||
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mController = spy(new DataUsagePreferenceController(mContext, "data_usage"));
|
||||
mController.init(SUB_ID);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_validSubId_returnAvailable() {
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_invalidSubId_returnUnsearchable() {
|
||||
mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE_UNSEARCHABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePreferenceTreeClick_needDialog_showDialog() {
|
||||
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
|
||||
doNothing().when(mContext).startActivity(captor.capture());
|
||||
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
|
||||
final Intent intent = captor.getValue();
|
||||
|
||||
assertThat(intent.getAction()).isEqualTo(Settings.ACTION_MOBILE_DATA_USAGE);
|
||||
assertThat(intent.getIntExtra(Settings.EXTRA_SUB_ID, 0)).isEqualTo(SUB_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_invalidSubId_disabled() {
|
||||
mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_noUsageData_shouldDisablePreference() {
|
||||
final DataUsageController.DataUsageInfo usageInfo =
|
||||
new DataUsageController.DataUsageInfo();
|
||||
doReturn(usageInfo).when(mController).getDataUsageInfo(any());
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_shouldUseIECUnit() {
|
||||
final DataUsageController.DataUsageInfo usageInfo =
|
||||
new DataUsageController.DataUsageInfo();
|
||||
usageInfo.usageLevel = DataUnit.MEBIBYTES.toBytes(1);
|
||||
doReturn(usageInfo).when(mController).getDataUsageInfo(any());
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getSummary().toString())
|
||||
.contains("1.00 MB");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.NetworkTemplate
|
||||
import android.provider.Settings
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.util.DataUnit
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.testing.TestLifecycleOwner
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||
import com.android.settings.core.BasePreferenceController.AVAILABLE
|
||||
import com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE
|
||||
import com.android.settings.datausage.DataUsageUtils
|
||||
import com.android.settingslib.net.DataUsageController
|
||||
import com.android.settingslib.net.DataUsageController.DataUsageInfo
|
||||
import com.android.settingslib.spa.testutils.waitUntil
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.doNothing
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoSession
|
||||
import org.mockito.Spy
|
||||
import org.mockito.quality.Strictness
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DataUsagePreferenceControllerTest {
|
||||
|
||||
private lateinit var mockSession: MockitoSession
|
||||
|
||||
@Spy
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
private lateinit var controller: DataUsagePreferenceController
|
||||
|
||||
private val preference = Preference(context)
|
||||
|
||||
@Mock
|
||||
private lateinit var networkTemplate: NetworkTemplate
|
||||
|
||||
@Mock
|
||||
private lateinit var dataUsageController: DataUsageController
|
||||
|
||||
@Mock
|
||||
private lateinit var preferenceScreen: PreferenceScreen
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mockSession = ExtendedMockito.mockitoSession()
|
||||
.initMocks(this)
|
||||
.mockStatic(SubscriptionManager::class.java)
|
||||
.spyStatic(DataUsageUtils::class.java)
|
||||
.strictness(Strictness.LENIENT)
|
||||
.startMocking()
|
||||
|
||||
whenever(SubscriptionManager.isValidSubscriptionId(SUB_ID)).thenReturn(true)
|
||||
ExtendedMockito.doReturn(true).`when` { DataUsageUtils.hasMobileData(context) }
|
||||
ExtendedMockito.doReturn(networkTemplate)
|
||||
.`when` { DataUsageUtils.getMobileTemplate(context, SUB_ID) }
|
||||
preference.key = TEST_KEY
|
||||
whenever(preferenceScreen.findPreference<Preference>(TEST_KEY)).thenReturn(preference)
|
||||
|
||||
controller =
|
||||
DataUsagePreferenceController(context, TEST_KEY).apply {
|
||||
init(SUB_ID)
|
||||
displayPreference(preferenceScreen)
|
||||
dataUsageControllerFactory = { dataUsageController }
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
mockSession.finishMocking()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_validSubId_returnAvailable() {
|
||||
assertThat(controller.availabilityStatus).isEqualTo(AVAILABLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getAvailabilityStatus_invalidSubId_returnUnsearchable() {
|
||||
controller.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
|
||||
|
||||
assertThat(controller.availabilityStatus).isEqualTo(AVAILABLE_UNSEARCHABLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun handlePreferenceTreeClick_startActivity() = runTest {
|
||||
val usageInfo = DataUsageInfo().apply {
|
||||
usageLevel = DataUnit.MEBIBYTES.toBytes(1)
|
||||
}
|
||||
whenever(dataUsageController.getDataUsageInfo(networkTemplate)).thenReturn(usageInfo)
|
||||
doNothing().`when`(context).startActivity(any())
|
||||
controller.whenViewCreated(TestLifecycleOwner(initialState = Lifecycle.State.STARTED))
|
||||
waitUntil { preference.summary != null }
|
||||
|
||||
controller.handlePreferenceTreeClick(preference)
|
||||
|
||||
val captor = ArgumentCaptor.forClass(Intent::class.java)
|
||||
verify(context).startActivity(captor.capture())
|
||||
val intent = captor.value
|
||||
assertThat(intent.action).isEqualTo(Settings.ACTION_MOBILE_DATA_USAGE)
|
||||
assertThat(intent.getIntExtra(Settings.EXTRA_SUB_ID, 0)).isEqualTo(SUB_ID)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateState_invalidSubId_disabled() = runTest {
|
||||
controller.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
|
||||
|
||||
controller.whenViewCreated(TestLifecycleOwner(initialState = Lifecycle.State.STARTED))
|
||||
|
||||
waitUntil { !preference.isEnabled }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateState_noUsageData_shouldDisablePreference() = runTest {
|
||||
val usageInfo = DataUsageInfo()
|
||||
whenever(dataUsageController.getDataUsageInfo(networkTemplate)).thenReturn(usageInfo)
|
||||
|
||||
controller.whenViewCreated(TestLifecycleOwner(initialState = Lifecycle.State.STARTED))
|
||||
|
||||
waitUntil { !preference.isEnabled }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateState_shouldUseIecUnit() = runTest {
|
||||
val usageInfo = DataUsageInfo().apply {
|
||||
usageLevel = DataUnit.MEBIBYTES.toBytes(1)
|
||||
}
|
||||
whenever(dataUsageController.getDataUsageInfo(networkTemplate)).thenReturn(usageInfo)
|
||||
|
||||
controller.whenViewCreated(TestLifecycleOwner(initialState = Lifecycle.State.STARTED))
|
||||
|
||||
waitUntil { preference.summary?.contains("1.00 MB") == true }
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TEST_KEY = "test_key"
|
||||
const val SUB_ID = 2
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user