• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.car.settings.datausage;
18 
19 import static com.android.car.settings.common.PreferenceController.AVAILABLE;
20 import static com.android.car.settings.common.PreferenceController.AVAILABLE_FOR_VIEWING;
21 import static com.android.car.settings.common.PreferenceController.CONDITIONALLY_UNAVAILABLE;
22 
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.spy;
29 import static org.mockito.Mockito.when;
30 
31 import android.car.drivingstate.CarUxRestrictions;
32 import android.content.Context;
33 import android.telephony.SubscriptionInfo;
34 import android.telephony.SubscriptionManager;
35 import android.telephony.SubscriptionPlan;
36 import android.telephony.TelephonyManager;
37 import android.text.TextUtils;
38 import android.text.format.Formatter;
39 
40 import androidx.lifecycle.LifecycleOwner;
41 import androidx.test.core.app.ApplicationProvider;
42 import androidx.test.ext.junit.runners.AndroidJUnit4;
43 
44 import com.android.car.settings.R;
45 import com.android.car.settings.common.FragmentController;
46 import com.android.car.settings.common.PreferenceControllerTestUtil;
47 import com.android.car.settings.testutils.TestLifecycleOwner;
48 import com.android.dx.mockito.inline.extended.ExtendedMockito;
49 import com.android.settingslib.net.DataUsageController;
50 
51 import com.google.android.collect.Lists;
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.Mock;
58 import org.mockito.MockitoAnnotations;
59 import org.mockito.MockitoSession;
60 
61 import java.time.Period;
62 import java.time.ZonedDateTime;
63 import java.util.concurrent.TimeUnit;
64 
65 @RunWith(AndroidJUnit4.class)
66 public class DataUsageSummaryPreferenceControllerTest {
67 
68     private static final CharSequence TEST_CARRIER_NAME = "TEST_CARRIER_NAME";
69     private static final int SUB_ID = 1;
70 
71     private Context mContext = spy(ApplicationProvider.getApplicationContext());
72     private LifecycleOwner mLifecycleOwner;
73     private CarUxRestrictions mCarUxRestrictions;
74     private DataUsageSummaryPreference mDataUsageSummaryPreference;
75     private DataUsageSummaryPreferenceController mPreferenceController;
76     private MockitoSession mSession;
77 
78     @Mock
79     private FragmentController mMockFragmentController;
80     @Mock
81     private DataUsageController mMockDataUsageController;
82     @Mock
83     private SubscriptionManager mMockSubscriptionManager;
84     @Mock
85     private TelephonyManager mMockTelephonyManager;
86 
87     @Before
setUp()88     public void setUp() {
89         MockitoAnnotations.initMocks(this);
90         mLifecycleOwner = new TestLifecycleOwner();
91 
92         mSession = ExtendedMockito.mockitoSession()
93                 .spyStatic(TelephonyManager.class)
94                 .startMocking();
95 
96         ExtendedMockito.when(TelephonyManager.from(mContext)).thenReturn(mMockTelephonyManager);
97         when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
98                 .thenReturn(mMockTelephonyManager);
99 
100         mCarUxRestrictions = new CarUxRestrictions.Builder(/* reqOpt= */ true,
101                 CarUxRestrictions.UX_RESTRICTIONS_BASELINE, /* timestamp= */ 0).build();
102         mPreferenceController = new DataUsageSummaryPreferenceController(mContext,
103                 /* preferenceKey= */ "key", mMockFragmentController,
104                 mCarUxRestrictions, mMockSubscriptionManager, mMockDataUsageController);
105         mDataUsageSummaryPreference = new DataUsageSummaryPreference(mContext);
106         mPreferenceController.setFields(SUB_ID);
107         PreferenceControllerTestUtil.assignPreference(mPreferenceController,
108                 mDataUsageSummaryPreference);
109 
110         SubscriptionInfo info = mock(SubscriptionInfo.class);
111         when(mMockSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(info);
112 
113         when(mMockTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_LOADED);
114     }
115 
116     @After
tearDown()117     public void tearDown() {
118         if (mSession != null) {
119             mSession.finishMocking();
120         }
121     }
122 
123     @Test
getAvailabilityStatus_hasSim_isAvailable()124     public void getAvailabilityStatus_hasSim_isAvailable() {
125         assertThat(mPreferenceController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
126     }
127 
128     @Test
getAvailabilityStatus_hasSim_isAvailable_zoneWrite()129     public void getAvailabilityStatus_hasSim_isAvailable_zoneWrite() {
130         mPreferenceController.setAvailabilityStatusForZone("write");
131         PreferenceControllerTestUtil.assertAvailability(
132                 mPreferenceController.getAvailabilityStatus(), AVAILABLE);
133     }
134 
135     @Test
getAvailabilityStatus_hasSim_isAvailable_zoneRead()136     public void getAvailabilityStatus_hasSim_isAvailable_zoneRead() {
137         mPreferenceController.setAvailabilityStatusForZone("read");
138         PreferenceControllerTestUtil.assertAvailability(
139                 mPreferenceController.getAvailabilityStatus(), AVAILABLE_FOR_VIEWING);
140     }
141 
142     @Test
getAvailabilityStatus_hasSim_isAvailable_zoneHidden()143     public void getAvailabilityStatus_hasSim_isAvailable_zoneHidden() {
144         mPreferenceController.setAvailabilityStatusForZone("hidden");
145         PreferenceControllerTestUtil.assertAvailability(
146                 mPreferenceController.getAvailabilityStatus(), CONDITIONALLY_UNAVAILABLE);
147     }
148 
149     @Test
getAvailabilityStatus_noSim_isConditionallyUnavailable()150     public void getAvailabilityStatus_noSim_isConditionallyUnavailable() {
151         when(mMockTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_UNKNOWN);
152         assertThat(mPreferenceController.getAvailabilityStatus())
153                 .isEqualTo(CONDITIONALLY_UNAVAILABLE);
154     }
155 
156     @Test
getAvailabilityStatus_noSim_isConditionallyUnavailable_zoneWrite()157     public void getAvailabilityStatus_noSim_isConditionallyUnavailable_zoneWrite() {
158         when(mMockTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_UNKNOWN);
159         mPreferenceController.setAvailabilityStatusForZone("write");
160         PreferenceControllerTestUtil.assertAvailability(
161                 mPreferenceController.getAvailabilityStatus(), CONDITIONALLY_UNAVAILABLE);
162     }
163 
164     @Test
getAvailabilityStatus_noSim_isConditionallyUnavailable_zoneRead()165     public void getAvailabilityStatus_noSim_isConditionallyUnavailable_zoneRead() {
166         when(mMockTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_UNKNOWN);
167         mPreferenceController.setAvailabilityStatusForZone("read");
168         PreferenceControllerTestUtil.assertAvailability(
169                 mPreferenceController.getAvailabilityStatus(), CONDITIONALLY_UNAVAILABLE);
170     }
171 
172     @Test
getAvailabilityStatus_noSim_isConditionallyUnavailable_zoneHidden()173     public void getAvailabilityStatus_noSim_isConditionallyUnavailable_zoneHidden() {
174         when(mMockTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_UNKNOWN);
175         mPreferenceController.setAvailabilityStatusForZone("hidden");
176         PreferenceControllerTestUtil.assertAvailability(
177                 mPreferenceController.getAvailabilityStatus(), CONDITIONALLY_UNAVAILABLE);
178     }
179 
180     @Test
refreshUi_hasUsage_titleSet()181     public void refreshUi_hasUsage_titleSet() {
182         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
183         info.usageLevel = 10000;
184         when(mMockDataUsageController.getDataUsageInfo(any())).thenReturn(info);
185 
186         mPreferenceController.onCreate(mLifecycleOwner);
187         mPreferenceController.refreshUi();
188 
189         String usedValueString = Formatter.formatBytes(mContext.getResources(), info.usageLevel,
190                 Formatter.FLAG_CALCULATE_ROUNDED | Formatter.FLAG_IEC_UNITS).value;
191         assertThat(mDataUsageSummaryPreference.getTitle().toString()).contains(usedValueString);
192     }
193 
194     @Test
refreshUi_hasCarrierName_hasRecentUpdate_setsCarrierInfoText()195     public void refreshUi_hasCarrierName_hasRecentUpdate_setsCarrierInfoText() {
196         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
197         info.usageLevel = 10000;
198         when(mMockDataUsageController.getDataUsageInfo(any())).thenReturn(info);
199 
200         setCarrierName(TEST_CARRIER_NAME);
201         setSubscriptionPlan(/* usageBytes= */ 1000L, System.currentTimeMillis());
202 
203         mPreferenceController.onCreate(mLifecycleOwner);
204         mPreferenceController.refreshUi();
205 
206         assertThat(mDataUsageSummaryPreference.getCarrierInfoText()).isEqualTo(
207                 TextUtils.expandTemplate(mContext.getText(R.string.carrier_and_update_now_text),
208                         TEST_CARRIER_NAME));
209     }
210 
211     @Test
refreshUi_hasCarrierName_hasOldUpdate_setsCarrierInfoText()212     public void refreshUi_hasCarrierName_hasOldUpdate_setsCarrierInfoText() {
213         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
214         info.usageLevel = 10000;
215         when(mMockDataUsageController.getDataUsageInfo(any())).thenReturn(info);
216 
217         int numDays = 15;
218         setCarrierName(TEST_CARRIER_NAME);
219         setSubscriptionPlan(/* usageBytes= */ 1000L,
220                 System.currentTimeMillis() - TimeUnit.DAYS.toMillis(numDays));
221 
222         mPreferenceController.onCreate(mLifecycleOwner);
223         mPreferenceController.refreshUi();
224 
225         assertThat(mDataUsageSummaryPreference.getCarrierInfoText()).isEqualTo(
226                 TextUtils.expandTemplate(mContext.getText(R.string.carrier_and_update_text),
227                         TEST_CARRIER_NAME, numDays + " days"));
228     }
229 
230     @Test
refreshUi_noCarrierName_hasRecentUpdate_setsCarrierInfoText()231     public void refreshUi_noCarrierName_hasRecentUpdate_setsCarrierInfoText() {
232         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
233         info.usageLevel = 10000;
234         when(mMockDataUsageController.getDataUsageInfo(any())).thenReturn(info);
235 
236         setSubscriptionPlan(/* usageBytes= */ 1000L, System.currentTimeMillis());
237 
238         mPreferenceController.onCreate(mLifecycleOwner);
239         mPreferenceController.refreshUi();
240 
241         assertThat(mDataUsageSummaryPreference.getCarrierInfoText().toString()).isEqualTo(
242                 mContext.getString(R.string.no_carrier_update_now_text));
243     }
244 
245     @Test
refreshUi_noCarrierName_hasOldUpdate_setsCarrierInfoText()246     public void refreshUi_noCarrierName_hasOldUpdate_setsCarrierInfoText() {
247         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
248         info.usageLevel = 10000;
249         when(mMockDataUsageController.getDataUsageInfo(any())).thenReturn(info);
250 
251         int numDays = 15;
252         setSubscriptionPlan(/* usageBytes= */ 1000L,
253                 System.currentTimeMillis() - TimeUnit.DAYS.toMillis(numDays));
254 
255         mPreferenceController.onCreate(mLifecycleOwner);
256         mPreferenceController.refreshUi();
257 
258         assertThat(mDataUsageSummaryPreference.getCarrierInfoText()).isEqualTo(
259                 TextUtils.expandTemplate(mContext.getText(R.string.no_carrier_update_text),
260                         null, numDays + " days"));
261     }
262 
263     @Test
refreshUi_hasUpdateTimeOlderThanWarning_setsCarrierInfoStyle()264     public void refreshUi_hasUpdateTimeOlderThanWarning_setsCarrierInfoStyle() {
265         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
266         info.usageLevel = 10000;
267         when(mMockDataUsageController.getDataUsageInfo(any())).thenReturn(info);
268 
269 
270         // Subtract an extra hour to account fo the difference in calls to
271         // System.currentTimeMillis().
272         setSubscriptionPlan(/* usageBytes= */ 1000L,
273                 System.currentTimeMillis() - DataUsageSummaryPreferenceController.WARNING_AGE
274                         - TimeUnit.HOURS.toMillis(1));
275 
276         mPreferenceController.onCreate(mLifecycleOwner);
277         mPreferenceController.refreshUi();
278 
279         assertThat(mDataUsageSummaryPreference.getCarrierInfoTextStyle()).isEqualTo(
280                 R.style.DataUsageSummaryCarrierInfoWarningTextAppearance);
281     }
282 
283     @Test
refreshUi_hasUpdateTimeYoungerThanWarning_setsCarrierInfoStyle()284     public void refreshUi_hasUpdateTimeYoungerThanWarning_setsCarrierInfoStyle() {
285         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
286         info.usageLevel = 10000;
287         when(mMockDataUsageController.getDataUsageInfo(any())).thenReturn(info);
288 
289         // Subtract an extra hour to account fo the difference in calls to
290         // System.currentTimeMillis().
291         setSubscriptionPlan(/* usageBytes= */ 1000L,
292                 System.currentTimeMillis() - DataUsageSummaryPreferenceController.WARNING_AGE
293                         + TimeUnit.HOURS.toMillis(1));
294 
295         mPreferenceController.onCreate(mLifecycleOwner);
296         mPreferenceController.refreshUi();
297 
298         assertThat(mDataUsageSummaryPreference.getCarrierInfoTextStyle()).isEqualTo(
299                 R.style.DataUsageSummaryCarrierInfoTextAppearance);
300     }
301 
setCarrierName(CharSequence name)302     private void setCarrierName(CharSequence name) {
303         SubscriptionInfo subInfo = new SubscriptionInfo(/* id= */ 0, /* iccId= */ "",
304                 /* simSlotIndex= */ 0, /* displayName= */ "", name,
305                 /* nameSource= */ 0, /* iconTint= */ 0, /* number= */ "",
306                 /* roaming= */ 0, /* icon= */ null, /* mcc= */ "", /* mnc= */ "",
307                 /* countryIso= */ "", /* isEmbedded= */ false,
308                 /* accessRules= */ null, /* cardString= */ "");
309         when(mMockSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(subInfo);
310     }
311 
setSubscriptionPlan(long usageBytes, long snapshotMillis)312     private void setSubscriptionPlan(long usageBytes, long snapshotMillis) {
313         ZonedDateTime start = ZonedDateTime.now();
314         ZonedDateTime end = ZonedDateTime.now().plusDays(30);
315         SubscriptionPlan plan = new SubscriptionPlan.Builder(start, end, Period.ofMonths(1))
316                 .setDataLimit(/* dataLimitBytes= */ 5000000000L,
317                         SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
318                 .setDataUsage(usageBytes, snapshotMillis)
319                 .build();
320         when(mMockSubscriptionManager.getSubscriptionPlans(anyInt()))
321                 .thenReturn(Lists.newArrayList(plan));
322     }
323 }
324