diff options
| author | 2016-10-25 18:31:02 +0000 | |
|---|---|---|
| committer | 2016-10-25 18:31:02 +0000 | |
| commit | a7bb5ad8097df828efe0271a63e581b19c2b96f0 (patch) | |
| tree | e5924d24916e77cc967f4175152b375e2b6bd4db | |
| parent | c8fceb983461115f1dd154a897d41f6000947548 (diff) | |
| parent | c29f2575f2f1224a3b08fe688975317f0d03c51b (diff) | |
Merge "Add unit tests for Tethering.isTetherProvisioningRequired" am: 836ffa6e1c
am: c29f2575f2
Change-Id: Ica704d0a64dde80ae0a9f1cef0250bfbdafcd49a
4 files changed, 168 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 614a94fa1e20..e8001c593b22 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -132,6 +132,7 @@ import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.DataConnectionStats; import com.android.server.connectivity.KeepaliveTracker; +import com.android.server.connectivity.MockableSystemProperties; import com.android.server.connectivity.Nat464Xlat; import com.android.server.connectivity.LingerMonitor; import com.android.server.connectivity.NetworkAgentInfo; @@ -815,7 +816,8 @@ public class ConnectivityService extends IConnectivityManager.Stub mTestMode = SystemProperties.get("cm.test.mode").equals("true") && SystemProperties.get("ro.build.type").equals("eng"); - mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager); + mTethering = new Tethering(mContext, mNetd, statsService, mPolicyManager, + IoThread.get().getLooper(), new MockableSystemProperties()); mPermissionMonitor = new PermissionMonitor(mContext, mNetd); diff --git a/services/core/java/com/android/server/connectivity/MockableSystemProperties.java b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java new file mode 100644 index 000000000000..4f68652d412c --- /dev/null +++ b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2016 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.server.connectivity; + +import android.os.SystemProperties; + +public class MockableSystemProperties { + public boolean getBoolean(String key, boolean def) { + return SystemProperties.getBoolean(key, def); + } +} diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index da9c5474b66b..da89723dca92 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -52,7 +52,6 @@ import android.os.Message; import android.os.Parcel; import android.os.RemoteException; import android.os.ResultReceiver; -import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.telephony.CarrierConfigManager; @@ -62,6 +61,7 @@ import android.util.ArrayMap; import android.util.Log; import android.util.SparseArray; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.IndentingPrintWriter; @@ -69,7 +69,6 @@ import com.android.internal.util.MessageUtils; import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.StateMachine; -import com.android.server.IoThread; import com.android.server.connectivity.tethering.IControlsTethering; import com.android.server.connectivity.tethering.IPv6TetheringCoordinator; import com.android.server.connectivity.tethering.TetherInterfaceStateMachine; @@ -100,6 +99,8 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering private final static boolean DBG = false; private final static boolean VDBG = false; + protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning"; + private static final Class[] messageClasses = { Tethering.class, TetherMasterSM.class, TetherInterfaceStateMachine.class }; @@ -127,6 +128,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering private final INetworkStatsService mStatsService; private final INetworkPolicyManager mPolicyManager; private final Looper mLooper; + private final MockableSystemProperties mSystemProperties; private static class TetherState { public final TetherInterfaceStateMachine mStateMachine; @@ -180,18 +182,19 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering private boolean mWifiTetherRequested; public Tethering(Context context, INetworkManagementService nmService, - INetworkStatsService statsService, INetworkPolicyManager policyManager) { + INetworkStatsService statsService, INetworkPolicyManager policyManager, + Looper looper, MockableSystemProperties systemProperties) { mContext = context; mNMService = nmService; mStatsService = statsService; mPolicyManager = policyManager; + mLooper = looper; + mSystemProperties = systemProperties; mPublicSync = new Object(); mTetherStates = new ArrayMap<>(); - // make our own thread so we don't anr the system - mLooper = IoThread.get().getLooper(); mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper); mTetherMasterSM.start(); @@ -394,10 +397,11 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering * * @return a boolean - {@code true} indicating tether provisioning is required by the carrier. */ - private boolean isTetherProvisioningRequired() { + @VisibleForTesting + protected boolean isTetherProvisioningRequired() { String[] provisionApp = mContext.getResources().getStringArray( com.android.internal.R.array.config_mobile_hotspot_provision_app); - if (SystemProperties.getBoolean("net.tethering.noprovisioning", false) + if (mSystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false) || provisionApp == null) { return false; } diff --git a/services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java b/services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java new file mode 100644 index 000000000000..a9f68c88c8c5 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2016 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.server.connectivity; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.res.Resources; +import android.net.INetworkPolicyManager; +import android.net.INetworkStatsService; +import android.os.INetworkManagementService; +import android.os.PersistableBundle; +import android.os.test.TestLooper; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.telephony.CarrierConfigManager; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class TetheringTest { + private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; + + @Mock private Context mContext; + @Mock private INetworkManagementService mNMService; + @Mock private INetworkStatsService mStatsService; + @Mock private INetworkPolicyManager mPolicyManager; + @Mock private MockableSystemProperties mSystemProperties; + @Mock private Resources mResources; + @Mock private CarrierConfigManager mCarrierConfigManager; + + // Like so many Android system APIs, these cannot be mocked because it is marked final. + // We have to use the real versions. + private final PersistableBundle mCarrierConfig = new PersistableBundle(); + private final TestLooper mLooper = new TestLooper(); + + private Tethering mTethering; + + @Before public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + when(mContext.getResources()).thenReturn(mResources); + when(mResources.getStringArray(com.android.internal.R.array.config_tether_dhcp_range)) + .thenReturn(new String[0]); + when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs)) + .thenReturn(new String[0]); + when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs)) + .thenReturn(new String[0]); + when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs)) + .thenReturn(new String[0]); + when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types)) + .thenReturn(new int[0]); + mTethering = new Tethering(mContext, mNMService, mStatsService, mPolicyManager, + mLooper.getLooper(), mSystemProperties); + } + + private void setupForRequiredProvisioning() { + // Produce some acceptable looking provision app setting if requested. + when(mResources.getStringArray( + com.android.internal.R.array.config_mobile_hotspot_provision_app)) + .thenReturn(PROVISIONING_APP_NAME); + // Don't disable tethering provisioning unless requested. + when(mSystemProperties.getBoolean(eq(Tethering.DISABLE_PROVISIONING_SYSPROP_KEY), + anyBoolean())).thenReturn(false); + // Act like the CarrierConfigManager is present and ready unless told otherwise. + when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) + .thenReturn(mCarrierConfigManager); + when(mCarrierConfigManager.getConfig()).thenReturn(mCarrierConfig); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); + } + + @Test + public void canRequireProvisioning() { + setupForRequiredProvisioning(); + assertTrue(mTethering.isTetherProvisioningRequired()); + } + + @Test + public void toleratesCarrierConfigManagerMissing() { + setupForRequiredProvisioning(); + when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) + .thenReturn(null); + // Couldn't get the CarrierConfigManager, but still had a declared provisioning app. + // We therefore still require provisioning. + assertTrue(mTethering.isTetherProvisioningRequired()); + } + + @Test + public void toleratesCarrierConfigMissing() { + setupForRequiredProvisioning(); + when(mCarrierConfigManager.getConfig()).thenReturn(null); + // We still have a provisioning app configured, so still require provisioning. + assertTrue(mTethering.isTetherProvisioningRequired()); + } + + @Test + public void provisioningNotRequiredWhenAppNotFound() { + setupForRequiredProvisioning(); + when(mResources.getStringArray( + com.android.internal.R.array.config_mobile_hotspot_provision_app)) + .thenReturn(null); + assertTrue(!mTethering.isTetherProvisioningRequired()); + when(mResources.getStringArray( + com.android.internal.R.array.config_mobile_hotspot_provision_app)) + .thenReturn(new String[] {"malformedApp"}); + assertTrue(!mTethering.isTetherProvisioningRequired()); + } +} |