1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.datausage; 18 19 import static android.net.ConnectivityManager.TYPE_WIFI; 20 21 import static com.android.settings.core.BasePreferenceController.AVAILABLE; 22 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.mockito.ArgumentMatchers.any; 27 import static org.mockito.Mockito.doReturn; 28 import static org.mockito.Mockito.spy; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 32 import android.app.Activity; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.net.ConnectivityManager; 36 import android.net.NetworkTemplate; 37 import android.telephony.SubscriptionManager; 38 import android.telephony.TelephonyManager; 39 40 import androidx.fragment.app.FragmentActivity; 41 import androidx.preference.PreferenceFragmentCompat; 42 import androidx.recyclerview.widget.RecyclerView; 43 44 import com.android.internal.logging.nano.MetricsProto; 45 import com.android.settings.R; 46 import com.android.settings.testutils.FakeFeatureFactory; 47 import com.android.settings.testutils.shadow.ShadowEntityHeaderController; 48 import com.android.settings.widget.EntityHeaderController; 49 import com.android.settingslib.NetworkPolicyEditor; 50 import com.android.settingslib.core.lifecycle.Lifecycle; 51 import com.android.settingslib.net.DataUsageController; 52 53 import org.junit.After; 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.mockito.Answers; 58 import org.mockito.ArgumentCaptor; 59 import org.mockito.Mock; 60 import org.mockito.MockitoAnnotations; 61 import org.robolectric.Robolectric; 62 import org.robolectric.RobolectricTestRunner; 63 import org.robolectric.RuntimeEnvironment; 64 import org.robolectric.annotation.Config; 65 66 import java.util.concurrent.TimeUnit; 67 68 @RunWith(RobolectricTestRunner.class) 69 @Config(shadows = ShadowEntityHeaderController.class) 70 public class DataUsageSummaryPreferenceControllerTest { 71 72 private static final long UPDATE_BACKOFF_MS = TimeUnit.MINUTES.toMillis(13); 73 private static final long CYCLE_BACKOFF_MS = TimeUnit.DAYS.toMillis(6); 74 private static final long CYCLE_LENGTH_MS = TimeUnit.DAYS.toMillis(30); 75 private static final long USAGE1 = 373 * BillingCycleSettings.MIB_IN_BYTES; 76 private static final long LIMIT1 = BillingCycleSettings.GIB_IN_BYTES; 77 private static final String CARRIER_NAME = "z-mobile"; 78 private static final String PERIOD = "Feb"; 79 80 @Mock 81 private DataUsageController mDataUsageController; 82 @Mock 83 private DataUsageSummaryPreference mSummaryPreference; 84 @Mock 85 private NetworkPolicyEditor mPolicyEditor; 86 @Mock 87 private NetworkTemplate mNetworkTemplate; 88 @Mock 89 private SubscriptionManager mSubscriptionManager; 90 @Mock 91 private Lifecycle mLifecycle; 92 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 93 private EntityHeaderController mHeaderController; 94 @Mock 95 private PreferenceFragmentCompat mPreferenceFragment; 96 @Mock 97 private TelephonyManager mTelephonyManager; 98 @Mock 99 private ConnectivityManager mConnectivityManager; 100 101 private DataUsageInfoController mDataInfoController; 102 103 private FakeFeatureFactory mFactory; 104 private FragmentActivity mActivity; 105 private Context mContext; 106 private DataUsageSummaryPreferenceController mController; 107 private int mDefaultSubscriptionId; 108 109 @Before setUp()110 public void setUp() { 111 MockitoAnnotations.initMocks(this); 112 mContext = spy(RuntimeEnvironment.application); 113 114 doReturn("%1$s %2%s").when(mContext) 115 .getString(com.android.internal.R.string.fileSizeSuffix); 116 117 mFactory = FakeFeatureFactory.setupForTest(); 118 when(mFactory.metricsFeatureProvider.getMetricsCategory(any(Object.class))) 119 .thenReturn(MetricsProto.MetricsEvent.SETTINGS_APP_NOTIF_CATEGORY); 120 ShadowEntityHeaderController.setUseMock(mHeaderController); 121 mDataInfoController = new DataUsageInfoController(); 122 123 mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get()); 124 when(mActivity.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); 125 when(mActivity.getSystemService(Context.CONNECTIVITY_SERVICE)) 126 .thenReturn(mConnectivityManager); 127 when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); 128 when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false); 129 mDefaultSubscriptionId = 1234; 130 mController = new DataUsageSummaryPreferenceController( 131 mDataUsageController, 132 mDataInfoController, 133 mNetworkTemplate, 134 mPolicyEditor, 135 R.string.cell_data_template, 136 true, 137 null, 138 mActivity, null, null, null, mDefaultSubscriptionId); 139 } 140 141 @After tearDown()142 public void tearDown() { 143 ShadowEntityHeaderController.reset(); 144 } 145 146 @Test testSummaryUpdate_onePlan_basic()147 public void testSummaryUpdate_onePlan_basic() { 148 final long now = System.currentTimeMillis(); 149 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 150 151 final Intent intent = new Intent(); 152 153 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 154 mController.setPlanValues(1 /* dataPlanCount */, LIMIT1, USAGE1); 155 mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); 156 157 mController.updateState(mSummaryPreference); 158 159 ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class); 160 verify(mSummaryPreference).setLimitInfo(captor.capture()); 161 CharSequence value = captor.getValue(); 162 assertThat(value.toString()).isEqualTo("512 MB data warning / 1.00 GB data limit"); 163 164 verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS, 165 CARRIER_NAME, 1 /* numPlans */, intent); 166 verify(mSummaryPreference).setChartEnabled(true); 167 verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */, 168 false /* isSingleWifi */); 169 } 170 171 @Test testSummaryUpdate_noPlan_basic()172 public void testSummaryUpdate_noPlan_basic() { 173 final long now = System.currentTimeMillis(); 174 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 175 176 final Intent intent = new Intent(); 177 178 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 179 mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); 180 mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); 181 182 mController.updateState(mSummaryPreference); 183 184 ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class); 185 verify(mSummaryPreference).setLimitInfo(captor.capture()); 186 CharSequence value = captor.getValue(); 187 assertThat(value.toString()).isEqualTo("512 MB data warning / 1.00 GB data limit"); 188 189 verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS, 190 CARRIER_NAME, 0 /* numPlans */, intent); 191 verify(mSummaryPreference).setChartEnabled(true); 192 verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */, 193 false /* isSingleWifi */); 194 } 195 196 @Test testSummaryUpdate_noCarrier_basic()197 public void testSummaryUpdate_noCarrier_basic() { 198 final long now = System.currentTimeMillis(); 199 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 200 201 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 202 mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); 203 mController.setCarrierValues(null /* carrierName */, -1L /* snapshotTime */, 204 info.cycleEnd, null /* intent */); 205 mController.updateState(mSummaryPreference); 206 207 ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class); 208 verify(mSummaryPreference).setLimitInfo(captor.capture()); 209 CharSequence value = captor.getValue(); 210 assertThat(value.toString()).isEqualTo("512 MB data warning / 1.00 GB data limit"); 211 212 verify(mSummaryPreference).setUsageInfo( 213 info.cycleEnd, 214 -1L /* snapshotTime */, 215 null /* carrierName */, 216 0 /* numPlans */, 217 null /* launchIntent */); 218 verify(mSummaryPreference).setChartEnabled(true); 219 verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */, 220 false /* isSingleWifi */); 221 } 222 223 @Test testSummaryUpdate_noPlanData_basic()224 public void testSummaryUpdate_noPlanData_basic() { 225 final long now = System.currentTimeMillis(); 226 227 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 228 229 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 230 mController.setPlanValues(0 /* dataPlanCount */, -1L /* dataPlanSize */, USAGE1); 231 mController.setCarrierValues(null /* carrierName */, -1L /* snapshotTime */, 232 info.cycleEnd, null /* intent */); 233 mController.updateState(mSummaryPreference); 234 235 ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class); 236 verify(mSummaryPreference).setLimitInfo(captor.capture()); 237 CharSequence value = captor.getValue(); 238 assertThat(value.toString()).isEqualTo("512 MB data warning / 1.00 GB data limit"); 239 verify(mSummaryPreference).setUsageInfo( 240 info.cycleEnd, 241 -1L /* snapshotTime */, 242 null /* carrierName */, 243 0 /* numPlans */, 244 null /* launchIntent */); 245 verify(mSummaryPreference).setChartEnabled(false); 246 verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */, 247 false /* isSingleWifi */); 248 } 249 250 @Test testSummaryUpdate_noLimitNoWarning()251 public void testSummaryUpdate_noLimitNoWarning() { 252 final long now = System.currentTimeMillis(); 253 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 254 info.warningLevel = 0L; 255 info.limitLevel = 0L; 256 257 final Intent intent = new Intent(); 258 259 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 260 mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); 261 mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); 262 263 mController.updateState(mSummaryPreference); 264 verify(mSummaryPreference).setLimitInfo(null); 265 } 266 267 @Test testSummaryUpdate_warningOnly()268 public void testSummaryUpdate_warningOnly() { 269 final long now = System.currentTimeMillis(); 270 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 271 info.warningLevel = BillingCycleSettings.MIB_IN_BYTES; 272 info.limitLevel = 0L; 273 274 final Intent intent = new Intent(); 275 276 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 277 mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); 278 mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); 279 280 mController.updateState(mSummaryPreference); 281 282 ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class); 283 verify(mSummaryPreference).setLimitInfo(captor.capture()); 284 CharSequence value = captor.getValue(); 285 assertThat(value.toString()).isEqualTo("1.00 MB data warning"); 286 } 287 288 @Test testSummaryUpdate_limitOnly()289 public void testSummaryUpdate_limitOnly() { 290 final long now = System.currentTimeMillis(); 291 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 292 info.warningLevel = 0L; 293 info.limitLevel = BillingCycleSettings.MIB_IN_BYTES; 294 295 final Intent intent = new Intent(); 296 297 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 298 mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); 299 mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); 300 301 mController.updateState(mSummaryPreference); 302 303 ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class); 304 verify(mSummaryPreference).setLimitInfo(captor.capture()); 305 CharSequence value = captor.getValue(); 306 assertThat(value.toString()).isEqualTo("1.00 MB data limit"); 307 } 308 309 @Test testSummaryUpdate_limitAndWarning()310 public void testSummaryUpdate_limitAndWarning() { 311 final long now = System.currentTimeMillis(); 312 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 313 info.warningLevel = BillingCycleSettings.MIB_IN_BYTES; 314 info.limitLevel = BillingCycleSettings.MIB_IN_BYTES; 315 316 final Intent intent = new Intent(); 317 318 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 319 mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); 320 mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); 321 322 mController.updateState(mSummaryPreference); 323 324 ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class); 325 verify(mSummaryPreference).setLimitInfo(captor.capture()); 326 CharSequence value = captor.getValue(); 327 assertThat(value.toString()).isEqualTo("1.00 MB data warning / 1.00 MB data limit"); 328 verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */, 329 false /* isSingleWifi */); 330 } 331 332 @Test testSummaryUpdate_noSim_shouldSetWifiMode()333 public void testSummaryUpdate_noSim_shouldSetWifiMode() { 334 final long now = System.currentTimeMillis(); 335 final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); 336 info.warningLevel = BillingCycleSettings.MIB_IN_BYTES; 337 info.limitLevel = BillingCycleSettings.MIB_IN_BYTES; 338 339 final Intent intent = new Intent(); 340 341 when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); 342 mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); 343 mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); 344 345 when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); 346 mController.updateState(mSummaryPreference); 347 348 verify(mSummaryPreference).setWifiMode(true /* isWifiMode */, info.period /* usagePeriod */, 349 false /* isSingleWifi */); 350 verify(mSummaryPreference).setLimitInfo(null); 351 verify(mSummaryPreference).setUsageNumbers(info.usageLevel, -1L, true); 352 verify(mSummaryPreference).setChartEnabled(false); 353 verify(mSummaryPreference).setUsageInfo(info.cycleEnd, -1L, null, 0, null); 354 } 355 356 @Test testMobileData_preferenceAvailable()357 public void testMobileData_preferenceAvailable() { 358 mController = new DataUsageSummaryPreferenceController( 359 mDataUsageController, 360 mDataInfoController, 361 mNetworkTemplate, 362 mPolicyEditor, 363 R.string.cell_data_template, 364 true, 365 mSubscriptionManager, 366 mActivity, null, null, null, mDefaultSubscriptionId); 367 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 368 } 369 370 @Test testMobileData_noSimNoWifi_preferenceDisabled()371 public void testMobileData_noSimNoWifi_preferenceDisabled() { 372 mController = new DataUsageSummaryPreferenceController( 373 mDataUsageController, 374 mDataInfoController, 375 mNetworkTemplate, 376 mPolicyEditor, 377 R.string.cell_data_template, 378 true, 379 mSubscriptionManager, 380 mActivity, null, null, null, mDefaultSubscriptionId); 381 382 when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); 383 when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false); 384 assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 385 } 386 387 @Test testMobileData_noSimWifi_preferenceDisabled()388 public void testMobileData_noSimWifi_preferenceDisabled() { 389 mController = new DataUsageSummaryPreferenceController( 390 mDataUsageController, 391 mDataInfoController, 392 mNetworkTemplate, 393 mPolicyEditor, 394 R.string.cell_data_template, 395 true, 396 mSubscriptionManager, 397 mActivity, null, null, null, mDefaultSubscriptionId); 398 399 when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); 400 when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(true); 401 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 402 } 403 404 @Test testMobileData_entityHeaderSet()405 public void testMobileData_entityHeaderSet() { 406 final RecyclerView recyclerView = new RecyclerView(mActivity); 407 408 mController = new DataUsageSummaryPreferenceController( 409 mDataUsageController, 410 mDataInfoController, 411 mNetworkTemplate, 412 mPolicyEditor, 413 R.string.cell_data_template, 414 true, 415 mSubscriptionManager, 416 mActivity, mLifecycle, mHeaderController, mPreferenceFragment, 417 mDefaultSubscriptionId); 418 419 when(mPreferenceFragment.getListView()).thenReturn(recyclerView); 420 421 mController.onStart(); 422 423 verify(mHeaderController) 424 .setRecyclerView(any(RecyclerView.class), any(Lifecycle.class)); 425 verify(mHeaderController).styleActionBar(any(Activity.class)); 426 } 427 createTestDataUsageInfo(long now)428 private DataUsageController.DataUsageInfo createTestDataUsageInfo(long now) { 429 DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo(); 430 info.carrier = CARRIER_NAME; 431 info.period = PERIOD; 432 info.startDate = now; 433 info.limitLevel = LIMIT1; 434 info.warningLevel = LIMIT1 >> 1; 435 info.usageLevel = USAGE1; 436 info.cycleStart = now - CYCLE_BACKOFF_MS; 437 info.cycleEnd = info.cycleStart + CYCLE_LENGTH_MS; 438 return info; 439 } 440 } 441