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