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
17package com.android.settings.datausage;
18
19import static android.net.ConnectivityManager.TYPE_WIFI;
20import static com.android.settings.core.BasePreferenceController.AVAILABLE;
21import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
22
23import static com.google.common.truth.Truth.assertThat;
24import static org.mockito.Matchers.any;
25import static org.mockito.Mockito.doReturn;
26import static org.mockito.Mockito.spy;
27import static org.mockito.Mockito.verify;
28import static org.mockito.Mockito.when;
29
30import android.app.Activity;
31import android.content.Context;
32import android.content.Intent;
33import android.net.ConnectivityManager;
34import android.net.NetworkTemplate;
35import android.support.v7.widget.RecyclerView;
36import android.telephony.SubscriptionInfo;
37import android.telephony.SubscriptionManager;
38import android.telephony.TelephonyManager;
39
40import com.android.internal.logging.nano.MetricsProto;
41import com.android.settings.R;
42import com.android.settings.testutils.FakeFeatureFactory;
43import com.android.settings.testutils.SettingsRobolectricTestRunner;
44import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
45import com.android.settings.widget.EntityHeaderController;
46import com.android.settingslib.NetworkPolicyEditor;
47import com.android.settingslib.core.lifecycle.Lifecycle;
48import com.android.settingslib.net.DataUsageController;
49
50import org.junit.After;
51import org.junit.Before;
52import org.junit.Test;
53import org.junit.runner.RunWith;
54import org.mockito.Answers;
55import org.mockito.Mock;
56import org.mockito.MockitoAnnotations;
57import org.robolectric.Robolectric;
58import org.robolectric.RuntimeEnvironment;
59import org.robolectric.annotation.Config;
60
61import java.util.concurrent.TimeUnit;
62
63@RunWith(SettingsRobolectricTestRunner.class)
64@Config(shadows = ShadowEntityHeaderController.class)
65public class DataUsageSummaryPreferenceControllerTest {
66
67    private static final long UPDATE_BACKOFF_MS = TimeUnit.MINUTES.toMillis(13);
68    private static final long CYCLE_BACKOFF_MS = TimeUnit.DAYS.toMillis(6);
69    private static final long CYCLE_LENGTH_MS = TimeUnit.DAYS.toMillis(30);
70    private static final long USAGE1 =  373 * BillingCycleSettings.MIB_IN_BYTES;
71    private static final long LIMIT1 = BillingCycleSettings.GIB_IN_BYTES;
72    private static final String CARRIER_NAME = "z-mobile";
73    private static final String PERIOD = "Feb";
74
75    @Mock
76    private DataUsageController mDataUsageController;
77    @Mock
78    private DataUsageSummaryPreference mSummaryPreference;
79    @Mock
80    private NetworkPolicyEditor mPolicyEditor;
81    @Mock
82    private NetworkTemplate mNetworkTemplate;
83    @Mock
84    private SubscriptionManager mSubscriptionManager;
85    @Mock
86    private Lifecycle mLifecycle;
87    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
88    private EntityHeaderController mHeaderController;
89    @Mock
90    private DataUsageSummary mDataUsageSummary;
91    @Mock
92    private TelephonyManager mTelephonyManager;
93    @Mock
94    private ConnectivityManager mConnectivityManager;
95
96    private DataUsageInfoController mDataInfoController;
97
98    private FakeFeatureFactory mFactory;
99    private Activity mActivity;
100    private Context mContext;
101    private DataUsageSummaryPreferenceController mController;
102
103    @Before
104    public void setUp() {
105        MockitoAnnotations.initMocks(this);
106        mContext = spy(RuntimeEnvironment.application);
107
108        doReturn("%1$s %2%s").when(mContext)
109            .getString(com.android.internal.R.string.fileSizeSuffix);
110
111        mFactory = FakeFeatureFactory.setupForTest();
112        when(mFactory.metricsFeatureProvider.getMetricsCategory(any(Object.class)))
113                .thenReturn(MetricsProto.MetricsEvent.SETTINGS_APP_NOTIF_CATEGORY);
114        ShadowEntityHeaderController.setUseMock(mHeaderController);
115        mDataInfoController = new DataUsageInfoController();
116
117        mActivity = spy(Robolectric.buildActivity(Activity.class).get());
118        when(mActivity.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
119        when(mActivity.getSystemService(ConnectivityManager.class))
120                .thenReturn(mConnectivityManager);
121        when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
122        when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false);
123        mController = new DataUsageSummaryPreferenceController(
124                mDataUsageController,
125                mDataInfoController,
126                mNetworkTemplate,
127                mPolicyEditor,
128                R.string.cell_data_template,
129                true,
130                null,
131                mActivity, null, null, null);
132    }
133
134    @After
135    public void tearDown() {
136        ShadowEntityHeaderController.reset();
137    }
138
139    @Test
140    public void testSummaryUpdate_onePlan_basic() {
141        final long now = System.currentTimeMillis();
142        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
143
144        final Intent intent = new Intent();
145
146        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
147        mController.setPlanValues(1 /* dataPlanCount */, LIMIT1, USAGE1);
148        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
149
150        mController.updateState(mSummaryPreference);
151        verify(mSummaryPreference).setLimitInfo("512 MB data warning / 1.00 GB data limit");
152        verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS,
153                CARRIER_NAME, 1 /* numPlans */, intent);
154        verify(mSummaryPreference).setChartEnabled(true);
155        verify(mSummaryPreference).setWifiMode(false, null);
156    }
157
158    @Test
159    public void testSummaryUpdate_noPlan_basic() {
160        final long now = System.currentTimeMillis();
161        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
162
163        final Intent intent = new Intent();
164
165        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
166        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
167        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
168
169        mController.updateState(mSummaryPreference);
170        verify(mSummaryPreference).setLimitInfo("512 MB data warning / 1.00 GB data limit");
171        verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS,
172                CARRIER_NAME, 0 /* numPlans */, intent);
173        verify(mSummaryPreference).setChartEnabled(true);
174        verify(mSummaryPreference).setWifiMode(false, null);
175    }
176
177    @Test
178    public void testSummaryUpdate_noCarrier_basic() {
179        final long now = System.currentTimeMillis();
180        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
181
182        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
183        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
184        mController.setCarrierValues(null /* carrierName */, -1L /* snapshotTime */,
185                info.cycleEnd, null /* intent */);
186        mController.updateState(mSummaryPreference);
187
188        verify(mSummaryPreference).setLimitInfo("512 MB data warning / 1.00 GB data limit");
189        verify(mSummaryPreference).setUsageInfo(
190                info.cycleEnd,
191                -1L /* snapshotTime */,
192                null /* carrierName */,
193                0 /* numPlans */,
194                null /* launchIntent */);
195        verify(mSummaryPreference).setChartEnabled(true);
196        verify(mSummaryPreference).setWifiMode(false, null);
197    }
198
199    @Test
200    public void testSummaryUpdate_noPlanData_basic() {
201        final long now = System.currentTimeMillis();
202
203        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
204
205        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
206        mController.setPlanValues(0 /* dataPlanCount */, -1L /* dataPlanSize */, USAGE1);
207        mController.setCarrierValues(null /* carrierName */, -1L /* snapshotTime */,
208                info.cycleEnd, null /* intent */);
209        mController.updateState(mSummaryPreference);
210
211        verify(mSummaryPreference).setLimitInfo("512 MB data warning / 1.00 GB data limit");
212        verify(mSummaryPreference).setUsageInfo(
213                info.cycleEnd,
214                -1L /* snapshotTime */,
215                null /* carrierName */,
216                0 /* numPlans */,
217                null /* launchIntent */);
218        verify(mSummaryPreference).setChartEnabled(false);
219        verify(mSummaryPreference).setWifiMode(false, null);
220    }
221
222    @Test
223    public void testSummaryUpdate_noLimitNoWarning() {
224        final long now = System.currentTimeMillis();
225        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
226        info.warningLevel = 0L;
227        info.limitLevel = 0L;
228
229        final Intent intent = new Intent();
230
231        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
232        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
233        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
234
235        mController.updateState(mSummaryPreference);
236        verify(mSummaryPreference).setLimitInfo(null);
237    }
238
239    @Test
240    public void testSummaryUpdate_warningOnly() {
241        final long now = System.currentTimeMillis();
242        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
243        info.warningLevel = BillingCycleSettings.MIB_IN_BYTES;
244        info.limitLevel = 0L;
245
246        final Intent intent = new Intent();
247
248        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
249        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
250        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
251
252        mController.updateState(mSummaryPreference);
253        verify(mSummaryPreference).setLimitInfo("1.00 MB data warning");
254    }
255
256    @Test
257    public void testSummaryUpdate_limitOnly() {
258        final long now = System.currentTimeMillis();
259        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
260        info.warningLevel = 0L;
261        info.limitLevel = BillingCycleSettings.MIB_IN_BYTES;
262
263        final Intent intent = new Intent();
264
265        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
266        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
267        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
268
269        mController.updateState(mSummaryPreference);
270        verify(mSummaryPreference).setLimitInfo("1.00 MB data limit");
271    }
272
273    @Test
274    public void testSummaryUpdate_limitAndWarning() {
275        final long now = System.currentTimeMillis();
276        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
277        info.warningLevel = BillingCycleSettings.MIB_IN_BYTES;
278        info.limitLevel = BillingCycleSettings.MIB_IN_BYTES;
279
280        final Intent intent = new Intent();
281
282        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
283        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
284        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
285
286        mController.updateState(mSummaryPreference);
287        verify(mSummaryPreference).setLimitInfo("1.00 MB data warning / 1.00 MB data limit");
288        verify(mSummaryPreference).setWifiMode(false, null);
289    }
290
291    @Test
292    public void testSummaryUpdate_noSim_shouldSetWifiMode() {
293        final long now = System.currentTimeMillis();
294        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
295        info.warningLevel = BillingCycleSettings.MIB_IN_BYTES;
296        info.limitLevel = BillingCycleSettings.MIB_IN_BYTES;
297
298        final Intent intent = new Intent();
299
300        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
301        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
302        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
303
304        when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT);
305        mController.updateState(mSummaryPreference);
306
307        verify(mSummaryPreference).setWifiMode(true, info.period);
308        verify(mSummaryPreference).setLimitInfo(null);
309        verify(mSummaryPreference).setUsageNumbers(info.usageLevel, -1L, true);
310        verify(mSummaryPreference).setChartEnabled(false);
311        verify(mSummaryPreference).setUsageInfo(info.cycleEnd, -1L, null, 0, null);
312    }
313
314    @Test
315    public void testMobileData_preferenceAvailable() {
316        mController = new DataUsageSummaryPreferenceController(
317                mDataUsageController,
318                mDataInfoController,
319                mNetworkTemplate,
320                mPolicyEditor,
321                R.string.cell_data_template,
322                true,
323                mSubscriptionManager,
324                mActivity, null, null, null);
325
326        final SubscriptionInfo subInfo = new SubscriptionInfo(0, "123456", 0, "name", "carrier",
327                0, 0, "number", 0, null, 123, 456, "ZX");
328        when(mSubscriptionManager.getDefaultDataSubscriptionInfo()).thenReturn(subInfo);
329        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
330    }
331
332    @Test
333    public void testMobileData_noSimNoWifi_preferenceDisabled() {
334        mController = new DataUsageSummaryPreferenceController(
335                mDataUsageController,
336                mDataInfoController,
337                mNetworkTemplate,
338                mPolicyEditor,
339                R.string.cell_data_template,
340                true,
341                mSubscriptionManager,
342                mActivity, null, null, null);
343
344        when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT);
345        when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false);
346        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
347    }
348
349    @Test
350    public void testMobileData_noSimWifi_preferenceDisabled() {
351        mController = new DataUsageSummaryPreferenceController(
352                mDataUsageController,
353                mDataInfoController,
354                mNetworkTemplate,
355                mPolicyEditor,
356                R.string.cell_data_template,
357                true,
358                mSubscriptionManager,
359                mActivity, null, null, null);
360
361        when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT);
362        when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(true);
363        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
364    }
365
366    @Test
367    public void testMobileData_entityHeaderSet() {
368        final RecyclerView recyclerView = new RecyclerView(mActivity);
369
370        mController = new DataUsageSummaryPreferenceController(
371                mDataUsageController,
372                mDataInfoController,
373                mNetworkTemplate,
374                mPolicyEditor,
375                R.string.cell_data_template,
376                true,
377                mSubscriptionManager,
378                mActivity, mLifecycle, mHeaderController, mDataUsageSummary);
379
380        when(mDataUsageSummary.getListView()).thenReturn(recyclerView);
381
382        mController.onStart();
383
384        verify(mHeaderController)
385                .setRecyclerView(any(RecyclerView.class), any(Lifecycle.class));
386        verify(mHeaderController).styleActionBar(any(Activity.class));
387    }
388
389    private DataUsageController.DataUsageInfo createTestDataUsageInfo(long now) {
390        DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
391        info.carrier = CARRIER_NAME;
392        info.period = PERIOD;
393        info.startDate = now;
394        info.limitLevel = LIMIT1;
395        info.warningLevel = LIMIT1 >> 1;
396        info.usageLevel = USAGE1;
397        info.cycleStart = now - CYCLE_BACKOFF_MS;
398        info.cycleEnd = info.cycleStart + CYCLE_LENGTH_MS;
399        return info;
400    }
401}
402