Fix broken DUN evaluation logic
Test: as follows
- built
- booted
- flashed
- runtest frameworks-net passes
Bug: 32163131
Bug: 38152109
Bug: 38186915
Merged-In: Ib9a469b16a598c47b615a15fc7cce420bfe4b8b7
Merged-In: I293b4cd57dcd1968c2b38f4e92e24cc0d2e135a9
Change-Id: Id4803504e825290d62c0b51a2b9bd664dcef30b1
(cherry picked from commit 54f2f3704e)
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server.connectivity.tethering;
|
package com.android.server.connectivity.tethering;
|
||||||
|
|
||||||
|
import static android.content.Context.TELEPHONY_SERVICE;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
||||||
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||||
@@ -47,9 +48,9 @@ import java.util.StringJoiner;
|
|||||||
public class TetheringConfiguration {
|
public class TetheringConfiguration {
|
||||||
private static final String TAG = TetheringConfiguration.class.getSimpleName();
|
private static final String TAG = TetheringConfiguration.class.getSimpleName();
|
||||||
|
|
||||||
private static final int DUN_NOT_REQUIRED = 0;
|
public static final int DUN_NOT_REQUIRED = 0;
|
||||||
private static final int DUN_REQUIRED = 1;
|
public static final int DUN_REQUIRED = 1;
|
||||||
private static final int DUN_UNSPECIFIED = 2;
|
public static final int DUN_UNSPECIFIED = 2;
|
||||||
|
|
||||||
// USB is 192.168.42.1 and 255.255.255.0
|
// USB is 192.168.42.1 and 255.255.255.0
|
||||||
// Wifi is 192.168.43.1 and 255.255.255.0
|
// Wifi is 192.168.43.1 and 255.255.255.0
|
||||||
@@ -81,8 +82,9 @@ public class TetheringConfiguration {
|
|||||||
tetherableBluetoothRegexs = ctx.getResources().getStringArray(
|
tetherableBluetoothRegexs = ctx.getResources().getStringArray(
|
||||||
com.android.internal.R.array.config_tether_bluetooth_regexs);
|
com.android.internal.R.array.config_tether_bluetooth_regexs);
|
||||||
|
|
||||||
isDunRequired = checkDunRequired(ctx);
|
final int dunCheck = checkDunRequired(ctx);
|
||||||
preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(ctx, isDunRequired);
|
preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(ctx, dunCheck);
|
||||||
|
isDunRequired = preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN);
|
||||||
|
|
||||||
dhcpRanges = getDhcpRanges(ctx);
|
dhcpRanges = getDhcpRanges(ctx);
|
||||||
defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
|
defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
|
||||||
@@ -138,14 +140,12 @@ public class TetheringConfiguration {
|
|||||||
pw.println();
|
pw.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkDunRequired(Context ctx) {
|
private static int checkDunRequired(Context ctx) {
|
||||||
final TelephonyManager tm = ctx.getSystemService(TelephonyManager.class);
|
final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
|
||||||
final int secureSetting =
|
return (tm != null) ? tm.getTetherApnRequired() : DUN_UNSPECIFIED;
|
||||||
(tm != null) ? tm.getTetherApnRequired() : DUN_UNSPECIFIED;
|
|
||||||
return (secureSetting == DUN_REQUIRED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Collection<Integer> getUpstreamIfaceTypes(Context ctx, boolean requiresDun) {
|
private static Collection<Integer> getUpstreamIfaceTypes(Context ctx, int dunCheck) {
|
||||||
final int ifaceTypes[] = ctx.getResources().getIntArray(
|
final int ifaceTypes[] = ctx.getResources().getIntArray(
|
||||||
com.android.internal.R.array.config_tether_upstream_types);
|
com.android.internal.R.array.config_tether_upstream_types);
|
||||||
final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
|
final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
|
||||||
@@ -153,10 +153,10 @@ public class TetheringConfiguration {
|
|||||||
switch (i) {
|
switch (i) {
|
||||||
case TYPE_MOBILE:
|
case TYPE_MOBILE:
|
||||||
case TYPE_MOBILE_HIPRI:
|
case TYPE_MOBILE_HIPRI:
|
||||||
if (requiresDun) continue;
|
if (dunCheck == DUN_REQUIRED) continue;
|
||||||
break;
|
break;
|
||||||
case TYPE_MOBILE_DUN:
|
case TYPE_MOBILE_DUN:
|
||||||
if (!requiresDun) continue;
|
if (dunCheck == DUN_NOT_REQUIRED) continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
upstreamIfaceTypes.add(i);
|
upstreamIfaceTypes.add(i);
|
||||||
@@ -166,7 +166,7 @@ public class TetheringConfiguration {
|
|||||||
// of the value of |requiresDun|, cell data of one form or another is
|
// of the value of |requiresDun|, cell data of one form or another is
|
||||||
// *always* an upstream, regardless of the upstream interface types
|
// *always* an upstream, regardless of the upstream interface types
|
||||||
// specified by configuration resources.
|
// specified by configuration resources.
|
||||||
if (requiresDun) {
|
if (dunCheck == DUN_REQUIRED) {
|
||||||
if (!upstreamIfaceTypes.contains(TYPE_MOBILE_DUN)) {
|
if (!upstreamIfaceTypes.contains(TYPE_MOBILE_DUN)) {
|
||||||
upstreamIfaceTypes.add(TYPE_MOBILE_DUN);
|
upstreamIfaceTypes.add(TYPE_MOBILE_DUN);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tethering;
|
||||||
|
|
||||||
|
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||||
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
|
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_NOT_REQUIRED;
|
||||||
|
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_REQUIRED;
|
||||||
|
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_UNSPECIFIED;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.ContextWrapper;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.support.test.filters.SmallTest;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
import com.android.internal.util.test.BroadcastInterceptingContext;
|
||||||
|
|
||||||
|
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 TetheringConfigurationTest {
|
||||||
|
@Mock private Context mContext;
|
||||||
|
@Mock private TelephonyManager mTelephonyManager;
|
||||||
|
@Mock private Resources mResources;
|
||||||
|
private Context mMockContext;
|
||||||
|
private boolean mHasTelephonyManager;
|
||||||
|
|
||||||
|
private class MockContext extends BroadcastInterceptingContext {
|
||||||
|
MockContext(Context base) {
|
||||||
|
super(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resources getResources() { return mResources; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getSystemService(String name) {
|
||||||
|
if (Context.TELEPHONY_SERVICE.equals(name)) {
|
||||||
|
return mHasTelephonyManager ? mTelephonyManager : null;
|
||||||
|
}
|
||||||
|
return super.getSystemService(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
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[]{ "test_wlan\\d" });
|
||||||
|
when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs))
|
||||||
|
.thenReturn(new String[0]);
|
||||||
|
mMockContext = new MockContext(mContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDunFromTelephonyManagerMeansDun() {
|
||||||
|
when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
|
||||||
|
.thenReturn(new int[]{TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI});
|
||||||
|
mHasTelephonyManager = true;
|
||||||
|
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_REQUIRED);
|
||||||
|
|
||||||
|
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext);
|
||||||
|
assertTrue(cfg.isDunRequired);
|
||||||
|
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
|
||||||
|
assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
|
||||||
|
assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI));
|
||||||
|
// Just to prove we haven't clobbered Wi-Fi:
|
||||||
|
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_WIFI));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDunNotRequiredFromTelephonyManagerMeansNoDun() {
|
||||||
|
when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
|
||||||
|
.thenReturn(new int[]{TYPE_MOBILE_DUN, TYPE_WIFI});
|
||||||
|
mHasTelephonyManager = true;
|
||||||
|
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_NOT_REQUIRED);
|
||||||
|
|
||||||
|
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext);
|
||||||
|
assertFalse(cfg.isDunRequired);
|
||||||
|
assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
|
||||||
|
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
|
||||||
|
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI));
|
||||||
|
// Just to prove we haven't clobbered Wi-Fi:
|
||||||
|
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_WIFI));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDunFromUpstreamConfigMeansDun() {
|
||||||
|
when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
|
||||||
|
.thenReturn(new int[]{TYPE_MOBILE_DUN, TYPE_WIFI});
|
||||||
|
mHasTelephonyManager = false;
|
||||||
|
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
|
||||||
|
|
||||||
|
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext);
|
||||||
|
assertTrue(cfg.isDunRequired);
|
||||||
|
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
|
||||||
|
// Just to prove we haven't clobbered Wi-Fi:
|
||||||
|
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_WIFI));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user