Loading services/core/java/com/android/server/ConnectivityService.java +3 −1 Original line number Diff line number Diff line Loading @@ -128,6 +128,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.NetworkAgentInfo; import com.android.server.connectivity.NetworkDiagnostics; Loading Loading @@ -760,7 +761,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); Loading services/core/java/com/android/server/connectivity/MockableSystemProperties.java 0 → 100644 +25 −0 Original line number Diff line number Diff line /* * 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); } } services/core/java/com/android/server/connectivity/Tethering.java +11 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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.TetherInterfaceStateMachine; import com.android.server.net.BaseNetworkObserver; Loading Loading @@ -99,6 +98,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 }; Loading Loading @@ -126,6 +127,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; Loading Loading @@ -179,18 +181,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(); Loading Loading @@ -393,10 +396,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; } Loading services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * 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()); } } Loading
services/core/java/com/android/server/ConnectivityService.java +3 −1 Original line number Diff line number Diff line Loading @@ -128,6 +128,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.NetworkAgentInfo; import com.android.server.connectivity.NetworkDiagnostics; Loading Loading @@ -760,7 +761,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); Loading
services/core/java/com/android/server/connectivity/MockableSystemProperties.java 0 → 100644 +25 −0 Original line number Diff line number Diff line /* * 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); } }
services/core/java/com/android/server/connectivity/Tethering.java +11 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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.TetherInterfaceStateMachine; import com.android.server.net.BaseNetworkObserver; Loading Loading @@ -99,6 +98,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 }; Loading Loading @@ -126,6 +127,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; Loading Loading @@ -179,18 +181,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(); Loading Loading @@ -393,10 +396,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; } Loading
services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * 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()); } }