blob: 73eddd166f8827d0d65ec16db1fc339560fa6d7b [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.connectivity;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Intent;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiInfo;
import android.os.Handler;
import android.os.Looper;
import android.telephony.CellSignalStrength;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import com.android.settingslib.graph.SignalDrawable;
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.R;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.util.CarrierConfigTracker;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
@Test
public void testNoIconWithoutMobile() {
// Turn off mobile network support.
when(mMockTm.isDataCapable()).thenReturn(false);
// Create a new NetworkController as this is currently handled in constructor.
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
mock(DumpManager.class));
setupNetworkController();
verifyLastMobileDataIndicators(false, -1, 0);
}
@Test
public void testServiceStateInitialState() throws Exception {
// Verify that NetworkControllerImpl pulls the service state from Telephony upon
// initialization rather than relying on the sticky behavior of ACTION_SERVICE_STATE
when(mServiceState.isEmergencyOnly()).thenReturn(true);
when(mMockTm.getServiceState()).thenReturn(mServiceState);
when(mMockSm.getCompleteActiveSubscriptionInfoList()).thenReturn(Collections.emptyList());
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
mock(DumpManager.class));
mNetworkController.registerListeners();
// Wait for the main looper to execute the previous command
Handler mainThreadHandler = new Handler(Looper.getMainLooper());
waitForIdleSync(mainThreadHandler);
verifyEmergencyOnly(true);
}
@Test
public void testNoSimsIconPresent() {
// No Subscriptions.
mNetworkController.mMobileSignalControllers.clear();
mNetworkController.updateNoSims();
verifyHasNoSims(true);
}
@Test
public void testEmergencyOnly() {
setupDefaultSignal();
mNetworkController.recalculateEmergency();
verifyEmergencyOnly(false);
mMobileSignalController.getState().isEmergency = true;
mNetworkController.recalculateEmergency();
verifyEmergencyOnly(true);
}
@Test
public void testEmergencyOnlyNoSubscriptions() {
setupDefaultSignal();
setSubscriptions();
mNetworkController.mLastServiceState = new ServiceState();
mNetworkController.mLastServiceState.setEmergencyOnly(true);
mNetworkController.recalculateEmergency();
verifyEmergencyOnly(true);
}
@Test
public void testNoEmergencyOnlyWrongSubscription() {
setupDefaultSignal();
setDefaultSubId(42);
mNetworkController.recalculateEmergency();
verifyEmergencyOnly(false);
}
@Test
public void testNoEmengencyNoSubscriptions() {
setupDefaultSignal();
setSubscriptions();
mNetworkController.mLastServiceState = new ServiceState();
mNetworkController.mLastServiceState.setEmergencyOnly(false);
mNetworkController.recalculateEmergency();
verifyEmergencyOnly(false);
}
@Test
public void testNoSimlessIconWithoutMobile() {
// Turn off mobile network support.
when(mMockTm.isDataCapable()).thenReturn(false);
// Create a new NetworkController as this is currently handled in constructor.
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
mock(DumpManager.class));
setupNetworkController();
// No Subscriptions.
mNetworkController.mMobileSignalControllers.clear();
mNetworkController.updateNoSims();
verifyHasNoSims(false);
}
@Test
public void testSignalStrength() {
for (int testStrength = 0;
testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) {
setupDefaultSignal();
setLevel(testStrength);
verifyLastMobileDataIndicators(true,
testStrength, DEFAULT_ICON);
// Verify low inet number indexing.
setConnectivityViaCallbackInNetworkController(
NetworkCapabilities.TRANSPORT_CELLULAR, false, true, null);
verifyLastMobileDataIndicators(true,
testStrength, DEFAULT_ICON, false, false);
}
}
@Test
public void testCdmaSignalStrength() {
for (int testStrength = 0;
testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) {
setupDefaultSignal();
setCdma();
setLevel(testStrength);
verifyLastMobileDataIndicators(true,
testStrength,
TelephonyIcons.ICON_1X);
}
}
@Test
public void testSignalRoaming() {
for (int testStrength = 0;
testStrength < CellSignalStrength.getNumSignalStrengthLevels(); testStrength++) {
setupDefaultSignal();
setGsmRoaming(true);
setLevel(testStrength);
verifyLastMobileDataIndicators(true,
testStrength,
DEFAULT_ICON, true);
}
}
@Test
public void testCdmaSignalRoaming() {
for (int testStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
setupDefaultSignal();
setCdma();
setCdmaRoaming(true);
setLevel(testStrength);
verifyLastMobileDataIndicators(true,
testStrength,
TelephonyIcons.ICON_1X, true);
}
}
@Test
public void testRoamingNoService_DoesNotCrash() {
setupDefaultSignal();
setCdma();
mServiceState = null;
updateServiceState();
}
@Test
public void testQsSignalStrength() {
for (int testStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
setupDefaultSignal();
setLevel(testStrength);
verifyLastQsMobileDataIndicators(true,
testStrength,
DEFAULT_QS_ICON, false, false);
}
}
@Test
public void testCdmaQsSignalStrength() {
for (int testStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
setupDefaultSignal();
setCdma();
setLevel(testStrength);
verifyLastQsMobileDataIndicators(true,
testStrength,
TelephonyIcons.ICON_1X, false, false);
}
}
@Test
public void testNoBangWithWifi() {
setupDefaultSignal();
setConnectivityViaCallbackInNetworkController(
mMobileSignalController.mTransportType, false, false, null);
setConnectivityViaCallbackInNetworkController(
NetworkCapabilities.TRANSPORT_WIFI, true, true, mock(WifiInfo.class));
verifyLastMobileDataIndicators(true, DEFAULT_LEVEL, 0);
}
// Some tests of actual NetworkController code, just internals not display stuff
// TODO: Put this somewhere else, maybe in its own file.
@Test
public void testHasCorrectMobileControllers() {
int[] testSubscriptions = new int[]{1, 5, 3};
int notTestSubscription = 0;
MobileSignalController mobileSignalController = Mockito.mock(MobileSignalController.class);
mNetworkController.mMobileSignalControllers.clear();
List<SubscriptionInfo> subscriptions = new ArrayList<>();
for (int i = 0; i < testSubscriptions.length; i++) {
// Force the test controllers into NetworkController.
mNetworkController.mMobileSignalControllers.put(testSubscriptions[i],
mobileSignalController);
// Generate a list of subscriptions we will tell the NetworkController to use.
SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
subscriptions.add(mockSubInfo);
}
assertTrue(mNetworkController.hasCorrectMobileControllers(subscriptions));
// Add a subscription that the NetworkController doesn't know about.
SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
subscriptions.add(mockSubInfo);
assertFalse(mNetworkController.hasCorrectMobileControllers(subscriptions));
}
@Test
public void testSetCurrentSubscriptions() {
// We will not add one controller to make sure it gets created.
int indexToSkipController = 0;
// We will not add one subscription to make sure it's controller gets removed.
int indexToSkipSubscription = 1;
int[] testSubscriptions = new int[]{1, 5, 3};
MobileSignalController[] mobileSignalControllers = new MobileSignalController[]{
Mockito.mock(MobileSignalController.class),
Mockito.mock(MobileSignalController.class),
Mockito.mock(MobileSignalController.class),
};
mNetworkController.mMobileSignalControllers.clear();
List<SubscriptionInfo> subscriptions = new ArrayList<>();
for (int i = 0; i < testSubscriptions.length; i++) {
if (i != indexToSkipController) {
// Force the test controllers into NetworkController.
mNetworkController.mMobileSignalControllers.put(testSubscriptions[i],
mobileSignalControllers[i]);
}
if (i != indexToSkipSubscription) {
// Generate a list of subscriptions we will tell the NetworkController to use.
SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
subscriptions.add(mockSubInfo);
}
}
// We can only test whether unregister gets called if it thinks its in a listening
// state.
mNetworkController.mListening = true;
mNetworkController.setCurrentSubscriptionsLocked(subscriptions);
for (int i = 0; i < testSubscriptions.length; i++) {
if (i == indexToSkipController) {
// Make sure a controller was created despite us not adding one.
assertTrue(mNetworkController.mMobileSignalControllers.indexOfKey(
testSubscriptions[i]) >= 0);
} else if (i == indexToSkipSubscription) {
// Make sure the controller that did exist was removed
assertFalse(mNetworkController.mMobileSignalControllers.indexOfKey(
testSubscriptions[i]) >= 0);
} else {
// If a MobileSignalController is around it needs to not be unregistered.
Mockito.verify(mobileSignalControllers[i], Mockito.never())
.unregisterListener();
}
}
}
@Test
public void testHistorySize() {
// Verify valid history size, otherwise it gits printed out the wrong order and whatnot.
assertEquals(0, SignalController.HISTORY_SIZE & (SignalController.HISTORY_SIZE - 1));
}
private void setCdma() {
setIsGsm(false);
updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
TelephonyManager.NETWORK_TYPE_CDMA);
setCdmaRoaming(false);
}
@Test
public void testOnReceive_stringsUpdatedAction_spn() {
String expectedMNetworkName = "Test";
Intent intent = createStringsUpdatedIntent(true /* showSpn */,
expectedMNetworkName /* spn */,
false /* showPlmn */,
"NotTest" /* plmn */);
mNetworkController.onReceive(mContext, intent);
assertNetworkNameEquals(expectedMNetworkName);
}
@Test
public void testOnReceive_stringsUpdatedAction_plmn() {
String expectedMNetworkName = "Test";
Intent intent = createStringsUpdatedIntent(false /* showSpn */,
"NotTest" /* spn */,
true /* showPlmn */,
expectedMNetworkName /* plmn */);
mNetworkController.onReceive(mContext, intent);
assertNetworkNameEquals(expectedMNetworkName);
}
@Test
public void testOnReceive_stringsUpdatedAction_bothFalse() {
Intent intent = createStringsUpdatedIntent(false /* showSpn */,
"Irrelevant" /* spn */,
false /* showPlmn */,
"Irrelevant" /* plmn */);
mNetworkController.onReceive(mContext, intent);
String defaultNetworkName = mMobileSignalController
.getTextIfExists(
com.android.internal.R.string.lockscreen_carrier_default).toString();
assertNetworkNameEquals(defaultNetworkName);
}
@Test
public void testOnReceive_stringsUpdatedAction_bothTrueAndNull() {
Intent intent = createStringsUpdatedIntent(true /* showSpn */,
null /* spn */,
true /* showPlmn */,
null /* plmn */);
mNetworkController.onReceive(mContext, intent);
String defaultNetworkName = mMobileSignalController.getTextIfExists(
com.android.internal.R.string.lockscreen_carrier_default).toString();
assertNetworkNameEquals(defaultNetworkName);
}
@Test
public void testOnReceive_stringsUpdatedAction_bothTrueAndNonNull() {
String spn = "Test1";
String plmn = "Test2";
Intent intent = createStringsUpdatedIntent(true /* showSpn */,
spn /* spn */,
true /* showPlmn */,
plmn /* plmn */);
mNetworkController.onReceive(mContext, intent);
assertNetworkNameEquals(plmn
+ mMobileSignalController.getTextIfExists(
R.string.status_bar_network_name_separator).toString()
+ spn);
}
private Intent createStringsUpdatedIntent(boolean showSpn, String spn,
boolean showPlmn, String plmn) {
Intent intent = new Intent();
intent.setAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
intent.putExtra(TelephonyManager.EXTRA_SHOW_SPN, showSpn);
intent.putExtra(TelephonyManager.EXTRA_SPN, spn);
intent.putExtra(TelephonyManager.EXTRA_SHOW_PLMN, showPlmn);
intent.putExtra(TelephonyManager.EXTRA_PLMN, plmn);
SubscriptionManager.putSubscriptionIdExtra(intent, mSubId);
return intent;
}
@Test
public void testOnUpdateDataActivity_dataIn() {
setupDefaultSignal();
updateDataActivity(TelephonyManager.DATA_ACTIVITY_IN);
verifyLastQsMobileDataIndicators(true /* visible */,
DEFAULT_LEVEL /* icon */,
DEFAULT_QS_ICON /* typeIcon */,
true /* dataIn */,
false /* dataOut */);
}
@Test
public void testOnUpdateDataActivity_dataOut() {
setupDefaultSignal();
updateDataActivity(TelephonyManager.DATA_ACTIVITY_OUT);
verifyLastQsMobileDataIndicators(true /* visible */,
DEFAULT_LEVEL /* icon */,
DEFAULT_QS_ICON /* typeIcon */,
false /* dataIn */,
true /* dataOut */);
}
@Test
public void testOnUpdateDataActivity_dataInOut() {
setupDefaultSignal();
updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
verifyLastQsMobileDataIndicators(true /* visible */,
DEFAULT_LEVEL /* icon */,
DEFAULT_QS_ICON /* typeIcon */,
true /* dataIn */,
true /* dataOut */);
}
@Test
public void testOnUpdateDataActivity_dataActivityNone() {
setupDefaultSignal();
updateDataActivity(TelephonyManager.DATA_ACTIVITY_NONE);
verifyLastQsMobileDataIndicators(true /* visible */,
DEFAULT_LEVEL /* icon */,
DEFAULT_QS_ICON /* typeIcon */,
false /* dataIn */,
false /* dataOut */);
}
@Test
public void testCarrierNetworkChange_carrierNetworkChange() {
int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
setupDefaultSignal();
setLevel(strength);
// Verify baseline
verifyLastMobileDataIndicators(true /* visible */,
strength /* strengthIcon */,
DEFAULT_ICON /* typeIcon */);
// API call is made
setCarrierNetworkChange(true /* enabled */);
// Carrier network change is true, show special indicator
verifyLastMobileDataIndicators(true /* visible */,
SignalDrawable.getCarrierChangeState(
CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */);
// Revert back
setCarrierNetworkChange(false /* enabled */);
// Verify back in previous state
verifyLastMobileDataIndicators(true /* visible */,
strength /* strengthIcon */,
DEFAULT_ICON /* typeIcon */);
}
@Test
public void testCarrierNetworkChange_roamingBeforeNetworkChange() {
int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
setupDefaultSignal();
setLevel(strength);
setGsmRoaming(true);
// Verify baseline
verifyLastMobileDataIndicators(true /* visible */,
strength /* strengthIcon */,
DEFAULT_ICON /* typeIcon */,
true /* roaming */);
// API call is made
setCarrierNetworkChange(true /* enabled */);
// Carrier network change is true, show special indicator, no roaming.
verifyLastMobileDataIndicators(true /* visible */,
SignalDrawable.getCarrierChangeState(
CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */,
false /* roaming */);
// Revert back
setCarrierNetworkChange(false /* enabled */);
// Verify back in previous state
verifyLastMobileDataIndicators(true /* visible */,
strength /* strengthIcon */,
DEFAULT_ICON /* typeIcon */,
true /* roaming */);
}
@Test
public void testCarrierNetworkChange_roamingAfterNetworkChange() {
int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
setupDefaultSignal();
setLevel(strength);
// Verify baseline
verifyLastMobileDataIndicators(true /* visible */,
strength /* strengthIcon */,
DEFAULT_ICON /* typeIcon */,
false /* roaming */);
// API call is made
setCarrierNetworkChange(true /* enabled */);
// Carrier network change is true, show special indicator, no roaming.
verifyLastMobileDataIndicators(true /* visible */,
SignalDrawable.getCarrierChangeState(
CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */,
false /* roaming */);
setGsmRoaming(true);
// Roaming should not show.
verifyLastMobileDataIndicators(true /* visible */,
SignalDrawable.getCarrierChangeState(
CellSignalStrength.getNumSignalStrengthLevels()),
0 /* typeIcon */,
false /* roaming */);
// Revert back
setCarrierNetworkChange(false /* enabled */);
// Verify back in previous state
verifyLastMobileDataIndicators(true /* visible */,
strength /* strengthIcon */,
DEFAULT_ICON /* typeIcon */,
true /* roaming */);
}
private void verifyEmergencyOnly(boolean isEmergencyOnly) {
ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
emergencyOnly.capture());
assertEquals(isEmergencyOnly, (boolean) emergencyOnly.getValue());
}
}