1/*
2 * Copyright (C) 2015 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 */
16package com.android.systemui.statusbar.policy;
17
18import static org.mockito.Mockito.mock;
19
20import android.content.Intent;
21import android.net.ConnectivityManager;
22import android.net.NetworkCapabilities;
23import android.os.Looper;
24import android.telephony.ServiceState;
25import android.telephony.SignalStrength;
26import android.telephony.SubscriptionInfo;
27import android.telephony.TelephonyManager;
28import android.test.suitebuilder.annotation.SmallTest;
29
30import com.android.internal.telephony.PhoneConstants;
31import com.android.internal.telephony.TelephonyIntents;
32import com.android.settingslib.net.DataUsageController;
33import com.android.systemui.R;
34
35import org.mockito.ArgumentCaptor;
36import org.mockito.Mockito;
37
38import java.util.ArrayList;
39import java.util.List;
40
41@SmallTest
42public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
43
44    public void testNoIconWithoutMobile() {
45        // Turn off mobile network support.
46        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
47        // Create a new NetworkController as this is currently handled in constructor.
48        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
49                mConfig, Looper.getMainLooper(), mCallbackHandler,
50                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
51                mMockSubDefaults);
52        setupNetworkController();
53
54        verifyLastMobileDataIndicators(false, 0, 0);
55    }
56
57    public void testNoSimsIconPresent() {
58        // No Subscriptions.
59        mNetworkController.mMobileSignalControllers.clear();
60        mNetworkController.updateNoSims();
61
62        verifyHasNoSims(true);
63    }
64
65    public void testEmergencyOnly() {
66        setupDefaultSignal();
67        mNetworkController.recalculateEmergency();
68        verifyEmergencyOnly(false);
69
70        mMobileSignalController.getState().isEmergency = true;
71        mNetworkController.recalculateEmergency();
72        verifyEmergencyOnly(true);
73    }
74
75    public void testEmergencyOnlyNoSubscriptions() {
76        setupDefaultSignal();
77        setSubscriptions();
78        mNetworkController.mLastServiceState = new ServiceState();
79        mNetworkController.mLastServiceState.setEmergencyOnly(true);
80        mNetworkController.recalculateEmergency();
81        verifyEmergencyOnly(true);
82    }
83
84    public void testNoEmengencyNoSubscriptions() {
85        setupDefaultSignal();
86        setSubscriptions();
87        mNetworkController.mLastServiceState = new ServiceState();
88        mNetworkController.mLastServiceState.setEmergencyOnly(false);
89        mNetworkController.recalculateEmergency();
90        verifyEmergencyOnly(false);
91    }
92
93    public void testNoSimlessIconWithoutMobile() {
94        // Turn off mobile network support.
95        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
96        // Create a new NetworkController as this is currently handled in constructor.
97        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
98                mConfig, Looper.getMainLooper(), mCallbackHandler,
99                mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
100                mMockSubDefaults);
101        setupNetworkController();
102
103        // No Subscriptions.
104        mNetworkController.mMobileSignalControllers.clear();
105        mNetworkController.updateNoSims();
106
107        verifyHasNoSims(false);
108    }
109
110    public void testSignalStrength() {
111        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
112                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
113            setupDefaultSignal();
114            setLevel(testStrength);
115
116            verifyLastMobileDataIndicators(true,
117                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength], DEFAULT_ICON);
118
119            // Verify low inet number indexing.
120            setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, true);
121            verifyLastMobileDataIndicators(true,
122                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[0][testStrength], DEFAULT_ICON);
123        }
124    }
125
126    public void testCdmaSignalStrength() {
127        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
128                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
129            setupDefaultSignal();
130            setCdma();
131            setLevel(testStrength);
132
133            verifyLastMobileDataIndicators(true,
134                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
135                    TelephonyIcons.DATA_1X[1][0 /* No direction */]);
136        }
137    }
138
139    public void testSignalRoaming() {
140        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
141                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
142            setupDefaultSignal();
143            setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
144            setGsmRoaming(true);
145            setLevel(testStrength);
146
147            verifyLastMobileDataIndicators(true,
148                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
149                    TelephonyIcons.ROAMING_ICON);
150        }
151    }
152
153    public void testCdmaSignalRoaming() {
154        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
155                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
156            setupDefaultSignal();
157            setCdma();
158            setCdmaRoaming(true);
159            setLevel(testStrength);
160
161            verifyLastMobileDataIndicators(true,
162                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
163                    TelephonyIcons.ROAMING_ICON);
164        }
165    }
166
167    public void testQsSignalStrength() {
168        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
169                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
170            setupDefaultSignal();
171            setLevel(testStrength);
172
173            verifyLastQsMobileDataIndicators(true,
174                    TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
175                    DEFAULT_QS_ICON, false, false);
176        }
177    }
178
179    public void testCdmaQsSignalStrength() {
180        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
181                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
182            setupDefaultSignal();
183            setCdma();
184            setLevel(testStrength);
185
186            verifyLastQsMobileDataIndicators(true,
187                    TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
188                    TelephonyIcons.QS_ICON_1X, false, false);
189        }
190    }
191
192    public void testNoBangWithWifi() {
193        setupDefaultSignal();
194        setConnectivity(mMobileSignalController.mTransportType, false, false);
195        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
196
197        verifyLastMobileDataIndicators(true, TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][2], 0);
198    }
199
200    // Some tests of actual NetworkController code, just internals not display stuff
201    // TODO: Put this somewhere else, maybe in its own file.
202    public void testHasCorrectMobileControllers() {
203        int[] testSubscriptions = new int[] { 1, 5, 3 };
204        int notTestSubscription = 0;
205        MobileSignalController mobileSignalController = Mockito.mock(MobileSignalController.class);
206
207        mNetworkController.mMobileSignalControllers.clear();
208        List<SubscriptionInfo> subscriptions = new ArrayList<>();
209        for (int i = 0; i < testSubscriptions.length; i++) {
210            // Force the test controllers into NetworkController.
211            mNetworkController.mMobileSignalControllers.put(testSubscriptions[i],
212                    mobileSignalController);
213
214            // Generate a list of subscriptions we will tell the NetworkController to use.
215            SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
216            Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
217            subscriptions.add(mockSubInfo);
218        }
219        assertTrue(mNetworkController.hasCorrectMobileControllers(subscriptions));
220
221        // Add a subscription that the NetworkController doesn't know about.
222        SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
223        Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
224        subscriptions.add(mockSubInfo);
225        assertFalse(mNetworkController.hasCorrectMobileControllers(subscriptions));
226    }
227
228    public void testSetCurrentSubscriptions() {
229        // We will not add one controller to make sure it gets created.
230        int indexToSkipController = 0;
231        // We will not add one subscription to make sure it's controller gets removed.
232        int indexToSkipSubscription = 1;
233
234        int[] testSubscriptions = new int[] { 1, 5, 3 };
235        MobileSignalController[] mobileSignalControllers = new MobileSignalController[] {
236                Mockito.mock(MobileSignalController.class),
237                Mockito.mock(MobileSignalController.class),
238                Mockito.mock(MobileSignalController.class),
239        };
240        mNetworkController.mMobileSignalControllers.clear();
241        List<SubscriptionInfo> subscriptions = new ArrayList<>();
242        for (int i = 0; i < testSubscriptions.length; i++) {
243            if (i != indexToSkipController) {
244                // Force the test controllers into NetworkController.
245                mNetworkController.mMobileSignalControllers.put(testSubscriptions[i],
246                        mobileSignalControllers[i]);
247            }
248
249            if (i != indexToSkipSubscription) {
250                // Generate a list of subscriptions we will tell the NetworkController to use.
251                SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
252                Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
253                Mockito.when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
254                subscriptions.add(mockSubInfo);
255            }
256        }
257
258        // We can only test whether unregister gets called if it thinks its in a listening
259        // state.
260        mNetworkController.mListening = true;
261        mNetworkController.setCurrentSubscriptions(subscriptions);
262
263        for (int i = 0; i < testSubscriptions.length; i++) {
264            if (i == indexToSkipController) {
265                // Make sure a controller was created despite us not adding one.
266                assertTrue(mNetworkController.mMobileSignalControllers.containsKey(
267                        testSubscriptions[i]));
268            } else if (i == indexToSkipSubscription) {
269                // Make sure the controller that did exist was removed
270                assertFalse(mNetworkController.mMobileSignalControllers.containsKey(
271                        testSubscriptions[i]));
272            } else {
273                // If a MobileSignalController is around it needs to not be unregistered.
274                Mockito.verify(mobileSignalControllers[i], Mockito.never())
275                        .unregisterListener();
276            }
277        }
278    }
279
280    public void testHistorySize() {
281        // Verify valid history size, otherwise it gits printed out the wrong order and whatnot.
282        assertEquals(0, SignalController.HISTORY_SIZE & (SignalController.HISTORY_SIZE - 1));
283    }
284
285    private void setCdma() {
286        setIsGsm(false);
287        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
288                TelephonyManager.NETWORK_TYPE_CDMA);
289        setCdmaRoaming(false);
290    }
291
292    public void testOnReceive_stringsUpdatedAction_spn() {
293        String expectedMNetworkName = "Test";
294        Intent intent = createStringsUpdatedIntent(true /* showSpn */,
295                expectedMNetworkName /* spn */,
296                false /* showPlmn */,
297                "NotTest" /* plmn */);
298
299        mNetworkController.onReceive(mContext, intent);
300
301        assertNetworkNameEquals(expectedMNetworkName);
302    }
303
304    public void testOnReceive_stringsUpdatedAction_plmn() {
305        String expectedMNetworkName = "Test";
306
307        Intent intent = createStringsUpdatedIntent(false /* showSpn */,
308                "NotTest" /* spn */,
309                true /* showPlmn */,
310                expectedMNetworkName /* plmn */);
311
312        mNetworkController.onReceive(mContext, intent);
313
314        assertNetworkNameEquals(expectedMNetworkName);
315    }
316
317    public void testOnReceive_stringsUpdatedAction_bothFalse() {
318        Intent intent = createStringsUpdatedIntent(false /* showSpn */,
319              "Irrelevant" /* spn */,
320              false /* showPlmn */,
321              "Irrelevant" /* plmn */);
322
323        mNetworkController.onReceive(mContext, intent);
324
325        String defaultNetworkName = mMobileSignalController
326            .getStringIfExists(
327                com.android.internal.R.string.lockscreen_carrier_default);
328        assertNetworkNameEquals(defaultNetworkName);
329    }
330
331    public void testOnReceive_stringsUpdatedAction_bothTrueAndNull() {
332        Intent intent = createStringsUpdatedIntent(true /* showSpn */,
333            null /* spn */,
334            true /* showPlmn */,
335            null /* plmn */);
336
337        mNetworkController.onReceive(mContext, intent);
338
339        String defaultNetworkName = mMobileSignalController.getStringIfExists(
340                com.android.internal.R.string.lockscreen_carrier_default);
341        assertNetworkNameEquals(defaultNetworkName);
342    }
343
344    public void testOnReceive_stringsUpdatedAction_bothTrueAndNonNull() {
345        String spn = "Test1";
346        String plmn = "Test2";
347
348        Intent intent = createStringsUpdatedIntent(true /* showSpn */,
349            spn /* spn */,
350            true /* showPlmn */,
351            plmn /* plmn */);
352
353        mNetworkController.onReceive(mContext, intent);
354
355        assertNetworkNameEquals(plmn
356                + mMobileSignalController.getStringIfExists(
357                        R.string.status_bar_network_name_separator)
358                + spn);
359    }
360
361    private Intent createStringsUpdatedIntent(boolean showSpn, String spn,
362            boolean showPlmn, String plmn) {
363
364        Intent intent = new Intent();
365        intent.setAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
366
367        intent.putExtra(TelephonyIntents.EXTRA_SHOW_SPN, showSpn);
368        intent.putExtra(TelephonyIntents.EXTRA_SPN, spn);
369
370        intent.putExtra(TelephonyIntents.EXTRA_SHOW_PLMN, showPlmn);
371        intent.putExtra(TelephonyIntents.EXTRA_PLMN, plmn);
372        intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, mSubId);
373
374        return intent;
375    }
376
377    public void testOnUpdateDataActivity_dataIn() {
378        setupDefaultSignal();
379
380        updateDataActivity(TelephonyManager.DATA_ACTIVITY_IN);
381
382        verifyLastQsMobileDataIndicators(true /* visible */,
383                TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL] /* icon */,
384                DEFAULT_QS_ICON /* typeIcon */,
385                true /* dataIn */,
386                false /* dataOut */);
387
388    }
389
390    public void testOnUpdateDataActivity_dataOut() {
391      setupDefaultSignal();
392
393      updateDataActivity(TelephonyManager.DATA_ACTIVITY_OUT);
394
395      verifyLastQsMobileDataIndicators(true /* visible */,
396              TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL] /* icon */,
397              DEFAULT_QS_ICON /* typeIcon */,
398              false /* dataIn */,
399              true /* dataOut */);
400
401    }
402
403    public void testOnUpdateDataActivity_dataInOut() {
404      setupDefaultSignal();
405
406      updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
407
408      verifyLastQsMobileDataIndicators(true /* visible */,
409              TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL] /* icon */,
410              DEFAULT_QS_ICON /* typeIcon */,
411              true /* dataIn */,
412              true /* dataOut */);
413
414    }
415
416    public void testOnUpdateDataActivity_dataActivityNone() {
417      setupDefaultSignal();
418
419      updateDataActivity(TelephonyManager.DATA_ACTIVITY_NONE);
420
421      verifyLastQsMobileDataIndicators(true /* visible */,
422              TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL] /* icon */,
423              DEFAULT_QS_ICON /* typeIcon */,
424              false /* dataIn */,
425              false /* dataOut */);
426
427    }
428
429    public void testCarrierNetworkChange_carrierNetworkChange() {
430      int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
431
432      setupDefaultSignal();
433      setLevel(strength);
434
435      // Verify baseline
436      verifyLastMobileDataIndicators(true /* visible */,
437              TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][strength] /* strengthIcon */,
438              DEFAULT_ICON /* typeIcon */);
439
440      // API call is made
441      setCarrierNetworkChange(true /* enabled */);
442
443      // Carrier network change is true, show special indicator
444      verifyLastMobileDataIndicators(true /* visible */,
445              TelephonyIcons.TELEPHONY_CARRIER_NETWORK_CHANGE[0][0] /* strengthIcon */,
446              0 /* typeIcon */);
447
448      // Revert back
449      setCarrierNetworkChange(false /* enabled */);
450
451      // Verify back in previous state
452      verifyLastMobileDataIndicators(true /* visible */,
453              TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][strength] /* strengthIcon */,
454              DEFAULT_ICON /* typeIcon */);
455    }
456
457    private void verifyEmergencyOnly(boolean isEmergencyOnly) {
458        ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
459        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
460                emergencyOnly.capture());
461        assertEquals(isEmergencyOnly, (boolean) emergencyOnly.getValue());
462    }
463}
464