• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.pm.PackageManager.FEATURE_WIFI;
20 
21 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
22 
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.eq;
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.content.Context;
33 import android.content.Intent;
34 import android.content.pm.PackageManager;
35 import android.net.NetworkTemplate;
36 import android.telephony.SubscriptionInfo;
37 import android.telephony.SubscriptionManager;
38 import android.telephony.SubscriptionPlan;
39 import android.telephony.TelephonyManager;
40 import android.util.RecurrenceRule;
41 
42 import androidx.fragment.app.FragmentActivity;
43 import androidx.preference.PreferenceFragmentCompat;
44 import androidx.recyclerview.widget.RecyclerView;
45 
46 import com.android.internal.logging.nano.MetricsProto;
47 import com.android.settings.R;
48 import com.android.settings.testutils.FakeFeatureFactory;
49 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
50 import com.android.settings.widget.EntityHeaderController;
51 import com.android.settingslib.NetworkPolicyEditor;
52 import com.android.settingslib.core.lifecycle.Lifecycle;
53 import com.android.settingslib.net.DataUsageController;
54 
55 import org.junit.After;
56 import org.junit.Before;
57 import org.junit.Test;
58 import org.junit.runner.RunWith;
59 import org.mockito.Answers;
60 import org.mockito.ArgumentCaptor;
61 import org.mockito.Mock;
62 import org.mockito.MockitoAnnotations;
63 import org.robolectric.Robolectric;
64 import org.robolectric.RobolectricTestRunner;
65 import org.robolectric.RuntimeEnvironment;
66 import org.robolectric.annotation.Config;
67 
68 import java.time.Instant;
69 import java.time.ZoneId;
70 import java.util.ArrayList;
71 import java.util.List;
72 import java.util.concurrent.TimeUnit;
73 
74 @RunWith(RobolectricTestRunner.class)
75 @Config(shadows = ShadowEntityHeaderController.class)
76 public class DataUsageSummaryPreferenceControllerTest {
77 
78     private static final long UPDATE_BACKOFF_MS = TimeUnit.MINUTES.toMillis(13);
79     private static final long CYCLE_BACKOFF_MS = TimeUnit.DAYS.toMillis(6);
80     private static final long CYCLE_LENGTH_MS = TimeUnit.DAYS.toMillis(30);
81     private static final long USAGE1 =  373 * BillingCycleSettings.MIB_IN_BYTES;
82     private static final long LIMIT1 = BillingCycleSettings.GIB_IN_BYTES;
83     private static final String CARRIER_NAME = "z-mobile";
84     private static final String PERIOD = "Feb";
85 
86     @Mock
87     private DataUsageController mDataUsageController;
88     @Mock
89     private DataUsageSummaryPreference mSummaryPreference;
90     @Mock
91     private NetworkPolicyEditor mPolicyEditor;
92     @Mock
93     private NetworkTemplate mNetworkTemplate;
94     @Mock
95     private SubscriptionInfo mSubscriptionInfo;
96     @Mock
97     private SubscriptionPlan mSubscriptionPlan;
98     @Mock
99     private Lifecycle mLifecycle;
100     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
101     private EntityHeaderController mHeaderController;
102     @Mock
103     private PreferenceFragmentCompat mPreferenceFragment;
104     @Mock
105     private TelephonyManager mTelephonyManager;
106     @Mock
107     private PackageManager mPm;
108 
109     private DataUsageInfoController mDataInfoController;
110 
111     private FakeFeatureFactory mFactory;
112     private FragmentActivity mActivity;
113     private Context mContext;
114     private DataUsageSummaryPreferenceController mController;
115     private int mDefaultSubscriptionId;
116     private List<SubscriptionPlan> mSubscriptionPlans;
117 
118     @Before
setUp()119     public void setUp() {
120         MockitoAnnotations.initMocks(this);
121         mContext = spy(RuntimeEnvironment.application);
122 
123         doReturn("%1$s %2%s").when(mContext)
124                 .getString(com.android.internal.R.string.fileSizeSuffix);
125 
126         mDefaultSubscriptionId = 1234;
127         mSubscriptionPlans = new ArrayList<SubscriptionPlan>();
128 
129         mFactory = FakeFeatureFactory.setupForTest();
130         when(mFactory.metricsFeatureProvider.getMetricsCategory(any(Object.class)))
131                 .thenReturn(MetricsProto.MetricsEvent.SETTINGS_APP_NOTIF_CATEGORY);
132         ShadowEntityHeaderController.setUseMock(mHeaderController);
133 
134         mDataInfoController = spy(new DataUsageInfoController());
135         doReturn(-1L).when(mDataInfoController).getSummaryLimit(any());
136 
137         mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get());
138         doReturn(mTelephonyManager).when(mActivity).getSystemService(TelephonyManager.class);
139         doReturn(mTelephonyManager).when(mTelephonyManager)
140                 .createForSubscriptionId(mDefaultSubscriptionId);
141         doReturn(mPm).when(mActivity).getPackageManager();
142         doReturn(false).when(mPm).hasSystemFeature(eq(FEATURE_WIFI));
143         doReturn(TelephonyManager.SIM_STATE_READY).when(mTelephonyManager).getSimState();
144 
145         mController = spy(new DataUsageSummaryPreferenceController(
146                 mDataUsageController,
147                 mDataInfoController,
148                 mNetworkTemplate,
149                 mPolicyEditor,
150                 R.string.cell_data_template,
151                 mActivity, null, null, null, mDefaultSubscriptionId));
152         doReturn(null).when(mController).getSubscriptionInfo(
153                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
154         doReturn(null).when(mController).getSubscriptionPlans(
155                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
156 
157         doReturn(CARRIER_NAME).when(mSubscriptionInfo).getCarrierName();
158         doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(mDefaultSubscriptionId);
159         doReturn(mSubscriptionPlans).when(mController).getSubscriptionPlans(mDefaultSubscriptionId);
160     }
161 
162     @After
tearDown()163     public void tearDown() {
164         ShadowEntityHeaderController.reset();
165     }
166 
167     @Test
testSummaryUpdate_onePlan_basic()168     public void testSummaryUpdate_onePlan_basic() {
169         final long now = System.currentTimeMillis();
170         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
171 
172         final Intent intent = new Intent();
173 
174         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
175         setupTestDataUsage(LIMIT1, USAGE1, now - UPDATE_BACKOFF_MS);
176         createTestDataPlan(info.cycleStart, info.cycleEnd);
177         doReturn(intent).when(mController).createManageSubscriptionIntent(mDefaultSubscriptionId);
178 
179         mController.updateState(mSummaryPreference);
180 
181         ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
182         verify(mSummaryPreference).setLimitInfo(captor.capture());
183         CharSequence value = captor.getValue();
184         assertThat(value.toString()).isEqualTo("512 MB data warning / 1.00 GB data limit");
185 
186         // TODO (b/170330084): return intent instead of null for mSummaryPreference
187         verify(mSummaryPreference).setUsageInfo((info.cycleEnd / 1000) * 1000,
188                 now - UPDATE_BACKOFF_MS,
189                 CARRIER_NAME, 1 /* numPlans */, null /* launchIntent */);
190         verify(mSummaryPreference).setChartEnabled(true);
191         verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */,
192                 false /* isSingleWifi */);
193     }
194 
195     @Test
testSummaryUpdate_noPlan_basic()196     public void testSummaryUpdate_noPlan_basic() {
197         final long now = System.currentTimeMillis();
198         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
199 
200         final Intent intent = new Intent();
201 
202         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
203         setupTestDataUsage(LIMIT1, USAGE1, now - UPDATE_BACKOFF_MS);
204 
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                 CARRIER_NAME,
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_noCarrier_basic()224     public void testSummaryUpdate_noCarrier_basic() {
225         final long now = System.currentTimeMillis();
226         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
227 
228         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
229         doReturn(null).when(mSubscriptionInfo).getCarrierName();
230         setupTestDataUsage(LIMIT1, USAGE1, -1L /* snapshotTime */);
231 
232         mController.updateState(mSummaryPreference);
233 
234         ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
235         verify(mSummaryPreference).setLimitInfo(captor.capture());
236         CharSequence value = captor.getValue();
237         assertThat(value.toString()).isEqualTo("512 MB data warning / 1.00 GB data limit");
238 
239         verify(mSummaryPreference).setUsageInfo(
240                 info.cycleEnd,
241                 -1L /* snapshotTime */,
242                 null /* carrierName */,
243                 0 /* numPlans */,
244                 null /* launchIntent */);
245         verify(mSummaryPreference).setChartEnabled(true);
246         verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */,
247                 false /* isSingleWifi */);
248     }
249 
250     @Test
testSummaryUpdate_noPlanData_basic()251     public void testSummaryUpdate_noPlanData_basic() {
252         final long now = System.currentTimeMillis();
253 
254         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
255 
256         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
257         doReturn(null).when(mSubscriptionInfo).getCarrierName();
258         setupTestDataUsage(-1L /* dataPlanSize */, USAGE1, -1L /* snapshotTime */);
259 
260         mController.updateState(mSummaryPreference);
261 
262         ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
263         verify(mSummaryPreference).setLimitInfo(captor.capture());
264         CharSequence value = captor.getValue();
265         assertThat(value.toString()).isEqualTo("512 MB data warning / 1.00 GB data limit");
266         verify(mSummaryPreference).setUsageInfo(
267                 info.cycleEnd,
268                 -1L /* snapshotTime */,
269                 null /* carrierName */,
270                 0 /* numPlans */,
271                 null /* launchIntent */);
272         verify(mSummaryPreference).setChartEnabled(false);
273         verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */,
274                 false /* isSingleWifi */);
275     }
276 
277     @Test
testSummaryUpdate_noLimitNoWarning()278     public void testSummaryUpdate_noLimitNoWarning() {
279         final long now = System.currentTimeMillis();
280         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
281         info.warningLevel = 0L;
282         info.limitLevel = 0L;
283 
284         final Intent intent = new Intent();
285 
286         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
287         setupTestDataUsage(LIMIT1, USAGE1, now - UPDATE_BACKOFF_MS);
288 
289         mController.updateState(mSummaryPreference);
290         verify(mSummaryPreference).setLimitInfo(null);
291     }
292 
293     @Test
testSummaryUpdate_warningOnly()294     public void testSummaryUpdate_warningOnly() {
295         final long now = System.currentTimeMillis();
296         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
297         info.warningLevel = BillingCycleSettings.MIB_IN_BYTES;
298         info.limitLevel = 0L;
299 
300         final Intent intent = new Intent();
301 
302         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
303         setupTestDataUsage(LIMIT1, USAGE1, now - UPDATE_BACKOFF_MS);
304 
305         mController.updateState(mSummaryPreference);
306 
307         ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
308         verify(mSummaryPreference).setLimitInfo(captor.capture());
309         CharSequence value = captor.getValue();
310         assertThat(value.toString()).isEqualTo("1.00 MB data warning");
311     }
312 
313     @Test
testSummaryUpdate_limitOnly()314     public void testSummaryUpdate_limitOnly() {
315         final long now = System.currentTimeMillis();
316         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
317         info.warningLevel = 0L;
318         info.limitLevel = BillingCycleSettings.MIB_IN_BYTES;
319 
320         final Intent intent = new Intent();
321 
322         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
323         setupTestDataUsage(LIMIT1, USAGE1, now - UPDATE_BACKOFF_MS);
324 
325         mController.updateState(mSummaryPreference);
326 
327         ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
328         verify(mSummaryPreference).setLimitInfo(captor.capture());
329         CharSequence value = captor.getValue();
330         assertThat(value.toString()).isEqualTo("1.00 MB data limit");
331     }
332 
333     @Test
testSummaryUpdate_limitAndWarning()334     public void testSummaryUpdate_limitAndWarning() {
335         final long now = System.currentTimeMillis();
336         final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
337         info.warningLevel = BillingCycleSettings.MIB_IN_BYTES;
338         info.limitLevel = BillingCycleSettings.MIB_IN_BYTES;
339 
340         final Intent intent = new Intent();
341 
342         doReturn(info).when(mDataUsageController).getDataUsageInfo(any());
343         setupTestDataUsage(LIMIT1, USAGE1, now - UPDATE_BACKOFF_MS);
344 
345         mController.updateState(mSummaryPreference);
346 
347         ArgumentCaptor<CharSequence> captor = ArgumentCaptor.forClass(CharSequence.class);
348         verify(mSummaryPreference).setLimitInfo(captor.capture());
349         CharSequence value = captor.getValue();
350         assertThat(value.toString()).isEqualTo("1.00 MB data warning / 1.00 MB data limit");
351         verify(mSummaryPreference).setWifiMode(false /* isWifiMode */, null /* usagePeriod */,
352                 false /* isSingleWifi */);
353     }
354 
355     @Test
testMobileData_preferenceAvailable()356     public void testMobileData_preferenceAvailable() {
357         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
358     }
359 
360     @Test
testMobileData_noSimWifi_preferenceDisabled()361     public void testMobileData_noSimWifi_preferenceDisabled() {
362         final int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
363         mController.init(subscriptionId);
364         mController.mDataUsageController = mDataUsageController;
365         doReturn(true).when(mPm).hasSystemFeature(eq(FEATURE_WIFI));
366         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
367     }
368 
369     @Test
testMobileData_entityHeaderSet()370     public void testMobileData_entityHeaderSet() {
371         final RecyclerView recyclerView = new RecyclerView(mActivity);
372 
373         mController = spy(new DataUsageSummaryPreferenceController(
374                 mDataUsageController,
375                 mDataInfoController,
376                 mNetworkTemplate,
377                 mPolicyEditor,
378                 R.string.cell_data_template,
379                 mActivity, mLifecycle, mHeaderController, mPreferenceFragment,
380                 mDefaultSubscriptionId));
381 
382         when(mPreferenceFragment.getListView()).thenReturn(recyclerView);
383 
384         mController.onStart();
385 
386         verify(mHeaderController)
387                 .setRecyclerView(any(RecyclerView.class), any(Lifecycle.class));
388     }
389 
createTestDataUsageInfo(long now)390     private DataUsageController.DataUsageInfo createTestDataUsageInfo(long now) {
391         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
392         info.carrier = CARRIER_NAME;
393         info.period = PERIOD;
394         info.startDate = now;
395         info.limitLevel = LIMIT1;
396         info.warningLevel = LIMIT1 >> 1;
397         info.usageLevel = USAGE1;
398         info.cycleStart = now - CYCLE_BACKOFF_MS;
399         info.cycleEnd = info.cycleStart + CYCLE_LENGTH_MS;
400         return info;
401     }
402 
setupTestDataUsage(long dataPlanSize, long dataUsageSize, long snapshotTime)403     private void setupTestDataUsage(long dataPlanSize, long dataUsageSize, long snapshotTime) {
404         doReturn(dataPlanSize).when(mSubscriptionPlan).getDataLimitBytes();
405         doReturn(dataUsageSize).when(mSubscriptionPlan).getDataUsageBytes();
406         doReturn(snapshotTime).when(mSubscriptionPlan).getDataUsageTime();
407 
408         doReturn(dataPlanSize).when(mDataInfoController).getSummaryLimit(any());
409     }
410 
createTestDataPlan(long startTime, long endTime)411     private void createTestDataPlan(long startTime, long endTime) {
412         final RecurrenceRule recurrenceRule = new RecurrenceRule(
413                 Instant.ofEpochMilli(startTime).atZone(ZoneId.systemDefault()),
414                 Instant.ofEpochMilli(endTime).atZone(ZoneId.systemDefault()),
415                 null);
416         doReturn(recurrenceRule).when(mSubscriptionPlan).getCycleRule();
417         mSubscriptionPlans.add(mSubscriptionPlan);
418     }
419 }
420