• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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  */
16 package android.tethering.mts;
17 
18 import static android.Manifest.permission.ACCESS_WIFI_STATE;
19 import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
20 import static android.Manifest.permission.NETWORK_SETTINGS;
21 import static android.Manifest.permission.READ_DEVICE_CONFIG;
22 import static android.Manifest.permission.TETHER_PRIVILEGED;
23 import static android.Manifest.permission.WRITE_SETTINGS;
24 import static android.net.TetheringManager.TETHERING_WIFI;
25 import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
26 
27 import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
28 
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertNotNull;
31 import static org.junit.Assert.fail;
32 import static org.junit.Assume.assumeTrue;
33 
34 import android.app.UiAutomation;
35 import android.content.Context;
36 import android.net.IpPrefix;
37 import android.net.LinkAddress;
38 import android.net.TetheringInterface;
39 import android.net.TetheringManager;
40 import android.net.cts.util.CtsTetheringUtils;
41 import android.net.cts.util.CtsTetheringUtils.TestTetheringEventCallback;
42 import android.provider.DeviceConfig;
43 
44 import androidx.annotation.NonNull;
45 import androidx.test.InstrumentationRegistry;
46 import androidx.test.runner.AndroidJUnit4;
47 
48 import com.android.testutils.TestNetworkTracker;
49 
50 import org.junit.After;
51 import org.junit.Before;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 
55 import java.net.InterfaceAddress;
56 import java.net.NetworkInterface;
57 import java.util.ArrayList;
58 import java.util.Arrays;
59 import java.util.List;
60 
61 @RunWith(AndroidJUnit4.class)
62 public class TetheringModuleTest {
63     private Context mContext;
64     private TetheringManager mTm;
65     private CtsTetheringUtils mCtsTetheringUtils;
66 
67     private UiAutomation mUiAutomation =
68             InstrumentationRegistry.getInstrumentation().getUiAutomation();
69 
70     @Before
setUp()71     public void setUp() throws Exception {
72         mUiAutomation.adoptShellPermissionIdentity(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS,
73                 WRITE_SETTINGS, READ_DEVICE_CONFIG, TETHER_PRIVILEGED, ACCESS_WIFI_STATE);
74         mContext = InstrumentationRegistry.getContext();
75         mTm = mContext.getSystemService(TetheringManager.class);
76         mCtsTetheringUtils = new CtsTetheringUtils(mContext);
77     }
78 
79     @After
tearDown()80     public void tearDown() throws Exception {
81         mUiAutomation.dropShellPermissionIdentity();
82     }
83 
84     private static final String TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES =
85             "tether_enable_select_all_prefix_ranges";
86     @Test
testSwitchBasePrefixRangeWhenConflict()87     public void testSwitchBasePrefixRangeWhenConflict() throws Exception {
88         assumeTrue(isFeatureEnabled(TETHER_ENABLE_SELECT_ALL_PREFIX_RANGES, true));
89 
90         addressConflictTest(true);
91     }
92 
93     @Test
testSwitchPrefixRangeWhenConflict()94     public void testSwitchPrefixRangeWhenConflict() throws Exception {
95         addressConflictTest(false);
96     }
97 
addressConflictTest(final boolean wholeRangeConflict)98     private void addressConflictTest(final boolean wholeRangeConflict) throws Exception {
99         final TestTetheringEventCallback tetherEventCallback =
100                 mCtsTetheringUtils.registerTetheringEventCallback();
101 
102         TestNetworkTracker tnt = null;
103         try {
104             tetherEventCallback.assumeWifiTetheringSupported(mContext);
105             tetherEventCallback.expectNoTetheringActive();
106 
107             final TetheringInterface tetheredIface =
108                     mCtsTetheringUtils.startWifiTethering(tetherEventCallback);
109 
110             assertNotNull(tetheredIface);
111             final String wifiTetheringIface = tetheredIface.getInterface();
112 
113             NetworkInterface nif = NetworkInterface.getByName(wifiTetheringIface);
114             // Tethering downstream only have one ipv4 address.
115             final LinkAddress hotspotAddr = getFirstIpv4Address(nif);
116             assertNotNull(hotspotAddr);
117 
118             final IpPrefix testPrefix = getConflictingPrefix(hotspotAddr, wholeRangeConflict);
119             assertNotNull(testPrefix);
120 
121             tnt = setUpTestNetwork(
122                     new LinkAddress(testPrefix.getAddress(), testPrefix.getPrefixLength()));
123 
124             tetherEventCallback.expectNoTetheringActive();
125             final List<String> wifiRegexs =
126                     tetherEventCallback.getTetheringInterfaceRegexps().getTetherableWifiRegexs();
127 
128             tetherEventCallback.expectTetheredInterfacesChanged(wifiRegexs, TETHERING_WIFI);
129             nif = NetworkInterface.getByName(wifiTetheringIface);
130             final LinkAddress newHotspotAddr = getFirstIpv4Address(nif);
131             assertNotNull(newHotspotAddr);
132 
133             assertFalse(testPrefix.containsPrefix(
134                     new IpPrefix(newHotspotAddr.getAddress(), newHotspotAddr.getPrefixLength())));
135 
136             mCtsTetheringUtils.stopWifiTethering(tetherEventCallback);
137         } finally {
138             if (tnt != null) {
139                 tnt.teardown();
140             }
141             mTm.stopAllTethering();
142             mCtsTetheringUtils.unregisterTetheringEventCallback(tetherEventCallback);
143         }
144     }
145 
getFirstIpv4Address(final NetworkInterface nif)146     private LinkAddress getFirstIpv4Address(final NetworkInterface nif) {
147         for (InterfaceAddress ia : nif.getInterfaceAddresses()) {
148             final LinkAddress addr = new LinkAddress(ia.getAddress(), ia.getNetworkPrefixLength());
149             if (addr.isIpv4()) return addr;
150         }
151         return null;
152     }
153 
154     @NonNull
getConflictingPrefix(final LinkAddress address, final boolean wholeRangeConflict)155     private IpPrefix getConflictingPrefix(final LinkAddress address,
156             final boolean wholeRangeConflict) {
157         if (!wholeRangeConflict) {
158             return new IpPrefix(address.getAddress(), address.getPrefixLength());
159         }
160 
161         final ArrayList<IpPrefix> prefixPool = new ArrayList<>(Arrays.asList(
162                 new IpPrefix("192.168.0.0/16"),
163                 new IpPrefix("172.16.0.0/12"),
164                 new IpPrefix("10.0.0.0/8")));
165 
166         for (IpPrefix prefix : prefixPool) {
167             if (prefix.contains(address.getAddress())) return prefix;
168         }
169 
170         fail("Could not find sutiable conflict prefix");
171 
172         // Never go here.
173         return null;
174     }
175 
setUpTestNetwork(final LinkAddress address)176     private TestNetworkTracker setUpTestNetwork(final LinkAddress address) throws Exception {
177         return initTestNetwork(mContext, address, 10_000L /* test timeout ms*/);
178 
179     }
180 
isFeatureEnabled(final String name, final boolean defaultValue)181     public static boolean isFeatureEnabled(final String name, final boolean defaultValue) {
182         return DeviceConfig.getBoolean(NAMESPACE_CONNECTIVITY, name, defaultValue);
183     }
184 }
185