• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 
17 package com.android.networkstack.tethering;
18 
19 import static android.Manifest.permission.NETWORK_SETTINGS;
20 import static android.content.pm.PackageManager.GET_ACTIVITIES;
21 import static android.hardware.usb.UsbManager.USB_CONFIGURED;
22 import static android.hardware.usb.UsbManager.USB_CONNECTED;
23 import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
24 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
25 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
26 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
27 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
28 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
29 import static android.net.ConnectivityManager.TYPE_WIFI;
30 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
31 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
32 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
33 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
34 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
35 import static android.net.RouteInfo.RTN_UNICAST;
36 import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
37 import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
38 import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
39 import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
40 import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
41 import static android.net.TetheringManager.TETHERING_BLUETOOTH;
42 import static android.net.TetheringManager.TETHERING_ETHERNET;
43 import static android.net.TetheringManager.TETHERING_NCM;
44 import static android.net.TetheringManager.TETHERING_USB;
45 import static android.net.TetheringManager.TETHERING_WIFI;
46 import static android.net.TetheringManager.TETHERING_WIFI_P2P;
47 import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
48 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
49 import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
50 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
51 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
52 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
53 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
54 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
55 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
56 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
57 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
58 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
59 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
60 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
61 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
62 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
63 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
64 
65 import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
66 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
67 import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
68 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
69 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
70 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
71 import static com.android.networkstack.tethering.TestConnectivityManager.BROADCAST_FIRST;
72 import static com.android.networkstack.tethering.TestConnectivityManager.CALLBACKS_FIRST;
73 import static com.android.networkstack.tethering.Tethering.UserRestrictionActionListener;
74 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS;
75 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_NCM_FUNCTION;
76 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION;
77 import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
78 import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES;
79 import static com.android.testutils.TestPermissionUtil.runAsShell;
80 
81 import static org.junit.Assert.assertArrayEquals;
82 import static org.junit.Assert.assertEquals;
83 import static org.junit.Assert.assertFalse;
84 import static org.junit.Assert.assertTrue;
85 import static org.junit.Assert.fail;
86 import static org.junit.Assume.assumeFalse;
87 import static org.junit.Assume.assumeTrue;
88 import static org.mockito.ArgumentMatchers.argThat;
89 import static org.mockito.ArgumentMatchers.notNull;
90 import static org.mockito.Matchers.anyInt;
91 import static org.mockito.Matchers.anyString;
92 import static org.mockito.Matchers.eq;
93 import static org.mockito.Mockito.any;
94 import static org.mockito.Mockito.doReturn;
95 import static org.mockito.Mockito.doThrow;
96 import static org.mockito.Mockito.inOrder;
97 import static org.mockito.Mockito.mock;
98 import static org.mockito.Mockito.never;
99 import static org.mockito.Mockito.reset;
100 import static org.mockito.Mockito.spy;
101 import static org.mockito.Mockito.timeout;
102 import static org.mockito.Mockito.times;
103 import static org.mockito.Mockito.verify;
104 import static org.mockito.Mockito.verifyNoMoreInteractions;
105 import static org.mockito.Mockito.when;
106 
107 import android.app.usage.NetworkStatsManager;
108 import android.bluetooth.BluetoothAdapter;
109 import android.bluetooth.BluetoothPan;
110 import android.bluetooth.BluetoothProfile;
111 import android.bluetooth.BluetoothProfile.ServiceListener;
112 import android.content.BroadcastReceiver;
113 import android.content.ContentResolver;
114 import android.content.Context;
115 import android.content.Intent;
116 import android.content.IntentFilter;
117 import android.content.pm.ApplicationInfo;
118 import android.content.pm.PackageManager;
119 import android.content.res.Resources;
120 import android.database.ContentObserver;
121 import android.hardware.usb.UsbManager;
122 import android.net.ConnectivityManager.NetworkCallback;
123 import android.net.EthernetManager;
124 import android.net.EthernetManager.TetheredInterfaceCallback;
125 import android.net.EthernetManager.TetheredInterfaceRequest;
126 import android.net.IConnectivityManager;
127 import android.net.IIntResultListener;
128 import android.net.INetd;
129 import android.net.ITetheringEventCallback;
130 import android.net.InetAddresses;
131 import android.net.InterfaceConfigurationParcel;
132 import android.net.IpPrefix;
133 import android.net.LinkAddress;
134 import android.net.LinkProperties;
135 import android.net.MacAddress;
136 import android.net.Network;
137 import android.net.NetworkCapabilities;
138 import android.net.NetworkRequest;
139 import android.net.RouteInfo;
140 import android.net.TetherStatesParcel;
141 import android.net.TetheredClient;
142 import android.net.TetheredClient.AddressInfo;
143 import android.net.TetheringCallbackStartedParcel;
144 import android.net.TetheringConfigurationParcel;
145 import android.net.TetheringInterface;
146 import android.net.TetheringManager;
147 import android.net.TetheringRequestParcel;
148 import android.net.dhcp.DhcpLeaseParcelable;
149 import android.net.dhcp.DhcpServerCallbacks;
150 import android.net.dhcp.DhcpServingParamsParcel;
151 import android.net.dhcp.IDhcpEventCallbacks;
152 import android.net.dhcp.IDhcpServer;
153 import android.net.ip.DadProxy;
154 import android.net.ip.IpNeighborMonitor;
155 import android.net.ip.IpServer;
156 import android.net.ip.RouterAdvertisementDaemon;
157 import android.net.util.NetworkConstants;
158 import android.net.util.SharedLog;
159 import android.net.wifi.SoftApConfiguration;
160 import android.net.wifi.WifiClient;
161 import android.net.wifi.WifiManager;
162 import android.net.wifi.WifiManager.SoftApCallback;
163 import android.net.wifi.p2p.WifiP2pGroup;
164 import android.net.wifi.p2p.WifiP2pInfo;
165 import android.net.wifi.p2p.WifiP2pManager;
166 import android.os.Build;
167 import android.os.Bundle;
168 import android.os.Handler;
169 import android.os.Looper;
170 import android.os.PersistableBundle;
171 import android.os.RemoteException;
172 import android.os.UserHandle;
173 import android.os.UserManager;
174 import android.os.test.TestLooper;
175 import android.provider.Settings;
176 import android.telephony.CarrierConfigManager;
177 import android.telephony.PhoneStateListener;
178 import android.telephony.TelephonyManager;
179 import android.test.mock.MockContentResolver;
180 import android.util.ArraySet;
181 
182 import androidx.annotation.NonNull;
183 import androidx.test.filters.SmallTest;
184 import androidx.test.runner.AndroidJUnit4;
185 
186 import com.android.internal.util.StateMachine;
187 import com.android.internal.util.test.BroadcastInterceptingContext;
188 import com.android.internal.util.test.FakeSettingsProvider;
189 import com.android.net.module.util.CollectionUtils;
190 import com.android.net.module.util.InterfaceParams;
191 import com.android.networkstack.apishim.common.BluetoothPanShim;
192 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
193 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
194 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
195 import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent;
196 import com.android.testutils.MiscAsserts;
197 
198 import org.junit.After;
199 import org.junit.Before;
200 import org.junit.BeforeClass;
201 import org.junit.Test;
202 import org.junit.runner.RunWith;
203 import org.mockito.ArgumentCaptor;
204 import org.mockito.InOrder;
205 import org.mockito.Mock;
206 import org.mockito.MockitoAnnotations;
207 
208 import java.io.FileDescriptor;
209 import java.io.PrintWriter;
210 import java.net.Inet4Address;
211 import java.net.Inet6Address;
212 import java.util.ArrayList;
213 import java.util.Arrays;
214 import java.util.Collection;
215 import java.util.Collections;
216 import java.util.List;
217 import java.util.Set;
218 import java.util.Vector;
219 
220 @RunWith(AndroidJUnit4.class)
221 @SmallTest
222 public class TetheringTest {
223     private static final int IFINDEX_OFFSET = 100;
224 
225     private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
226     private static final String TEST_DUN_IFNAME = "test_dun0";
227     private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
228     private static final String TEST_RNDIS_IFNAME = "test_rndis0";
229     private static final String TEST_WIFI_IFNAME = "test_wlan0";
230     private static final String TEST_WLAN_IFNAME = "test_wlan1";
231     private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
232     private static final String TEST_NCM_IFNAME = "test_ncm0";
233     private static final String TEST_ETH_IFNAME = "test_eth0";
234     private static final String TEST_BT_IFNAME = "test_pan0";
235     private static final String TETHERING_NAME = "Tethering";
236     private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
237     private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
238     private static final String TEST_RNDIS_REGEX = "test_rndis\\d";
239     private static final String TEST_NCM_REGEX = "test_ncm\\d";
240     private static final String TEST_WIFI_REGEX = "test_wlan\\d";
241     private static final String TEST_P2P_REGEX = "test_p2p-p2p\\d-.*";
242     private static final String TEST_BT_REGEX = "test_pan\\d";
243 
244     private static final int CELLULAR_NETID = 100;
245     private static final int WIFI_NETID = 101;
246     private static final int DUN_NETID = 102;
247 
248     private static final int TETHER_USB_RNDIS_NCM_FUNCTIONS = 2;
249 
250     private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
251 
252     @Mock private ApplicationInfo mApplicationInfo;
253     @Mock private Context mContext;
254     @Mock private NetworkStatsManager mStatsManager;
255     @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
256     @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats;
257     @Mock private Resources mResources;
258     @Mock private TelephonyManager mTelephonyManager;
259     @Mock private UsbManager mUsbManager;
260     @Mock private WifiManager mWifiManager;
261     @Mock private CarrierConfigManager mCarrierConfigManager;
262     @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
263     @Mock private DadProxy mDadProxy;
264     @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
265     @Mock private IpNeighborMonitor mIpNeighborMonitor;
266     @Mock private IDhcpServer mDhcpServer;
267     @Mock private INetd mNetd;
268     @Mock private UserManager mUserManager;
269     @Mock private EthernetManager mEm;
270     @Mock private TetheringNotificationUpdater mNotificationUpdater;
271     @Mock private BpfCoordinator mBpfCoordinator;
272     @Mock private PackageManager mPackageManager;
273     @Mock private BluetoothAdapter mBluetoothAdapter;
274     @Mock private BluetoothPan mBluetoothPan;
275     @Mock private BluetoothPanShim mBluetoothPanShim;
276     @Mock private TetheredInterfaceRequestShim mTetheredInterfaceRequestShim;
277 
278     private final MockIpServerDependencies mIpServerDependencies =
279             spy(new MockIpServerDependencies());
280     private final MockTetheringDependencies mTetheringDependencies =
281             new MockTetheringDependencies();
282 
283     // Like so many Android system APIs, these cannot be mocked because it is marked final.
284     // We have to use the real versions.
285     private final PersistableBundle mCarrierConfig = new PersistableBundle();
286     private final TestLooper mLooper = new TestLooper();
287 
288     private Vector<Intent> mIntents;
289     private BroadcastInterceptingContext mServiceContext;
290     private MockContentResolver mContentResolver;
291     private BroadcastReceiver mBroadcastReceiver;
292     private Tethering mTethering;
293     private PhoneStateListener mPhoneStateListener;
294     private InterfaceConfigurationParcel mInterfaceConfiguration;
295     private TetheringConfiguration mConfig;
296     private EntitlementManager mEntitleMgr;
297     private OffloadController mOffloadCtrl;
298     private PrivateAddressCoordinator mPrivateAddressCoordinator;
299     private SoftApCallback mSoftApCallback;
300     private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
301     private TetheredInterfaceCallbackShim mTetheredInterfaceCallbackShim;
302 
303     private TestConnectivityManager mCm;
304     private boolean mForceEthernetServiceUnavailable = false;
305 
306     private class TestContext extends BroadcastInterceptingContext {
TestContext(Context base)307         TestContext(Context base) {
308             super(base);
309         }
310 
311         @Override
getApplicationInfo()312         public ApplicationInfo getApplicationInfo() {
313             return mApplicationInfo;
314         }
315 
316         @Override
getContentResolver()317         public ContentResolver getContentResolver() {
318             return mContentResolver;
319         }
320 
321         @Override
getPackageName()322         public String getPackageName() {
323             return "TetheringTest";
324         }
325 
326         @Override
getResources()327         public Resources getResources() {
328             return mResources;
329         }
330 
331         @Override
getSystemService(String name)332         public Object getSystemService(String name) {
333             if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
334             if (Context.USB_SERVICE.equals(name)) return mUsbManager;
335             if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
336             if (Context.USER_SERVICE.equals(name)) return mUserManager;
337             if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
338             if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
339             if (Context.ETHERNET_SERVICE.equals(name)) {
340                 if (mForceEthernetServiceUnavailable) return null;
341 
342                 return mEm;
343             }
344             return super.getSystemService(name);
345         }
346 
347         @Override
getPackageManager()348         public PackageManager getPackageManager() {
349             return mPackageManager;
350         }
351 
352         @Override
getSystemServiceName(Class<?> serviceClass)353         public String getSystemServiceName(Class<?> serviceClass) {
354             if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
355             return super.getSystemServiceName(serviceClass);
356         }
357     }
358 
359     public class MockIpServerDependencies extends IpServer.Dependencies {
360         @Override
getDadProxy( Handler handler, InterfaceParams ifParams)361         public DadProxy getDadProxy(
362                 Handler handler, InterfaceParams ifParams) {
363             return mDadProxy;
364         }
365 
366         @Override
getRouterAdvertisementDaemon( InterfaceParams ifParams)367         public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
368                 InterfaceParams ifParams) {
369             return mRouterAdvertisementDaemon;
370         }
371 
372         @Override
getInterfaceParams(String ifName)373         public InterfaceParams getInterfaceParams(String ifName) {
374             assertTrue("Non-mocked interface " + ifName,
375                     ifName.equals(TEST_RNDIS_IFNAME)
376                             || ifName.equals(TEST_WLAN_IFNAME)
377                             || ifName.equals(TEST_WIFI_IFNAME)
378                             || ifName.equals(TEST_MOBILE_IFNAME)
379                             || ifName.equals(TEST_DUN_IFNAME)
380                             || ifName.equals(TEST_P2P_IFNAME)
381                             || ifName.equals(TEST_NCM_IFNAME)
382                             || ifName.equals(TEST_ETH_IFNAME)
383                             || ifName.equals(TEST_BT_IFNAME));
384             final String[] ifaces = new String[] {
385                     TEST_RNDIS_IFNAME, TEST_WLAN_IFNAME, TEST_WIFI_IFNAME, TEST_MOBILE_IFNAME,
386                     TEST_DUN_IFNAME, TEST_P2P_IFNAME, TEST_NCM_IFNAME, TEST_ETH_IFNAME};
387             return new InterfaceParams(ifName,
388                     CollectionUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
389                     MacAddress.ALL_ZEROS_ADDRESS);
390         }
391 
392         @Override
makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb)393         public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
394                 DhcpServerCallbacks cb) {
395             new Thread(() -> {
396                 try {
397                     cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer);
398                 } catch (RemoteException e) {
399                     fail(e.getMessage());
400                 }
401             }).run();
402         }
403 
getIpNeighborMonitor(Handler h, SharedLog l, IpNeighborMonitor.NeighborEventConsumer c)404         public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l,
405                 IpNeighborMonitor.NeighborEventConsumer c) {
406             return mIpNeighborMonitor;
407         }
408     }
409 
410     public class MockTetheringDependencies extends TetheringDependencies {
411         StateMachine mUpstreamNetworkMonitorSM;
412         ArrayList<IpServer> mIpv6CoordinatorNotifyList;
413 
414         @Override
getBpfCoordinator( BpfCoordinator.Dependencies deps)415         public BpfCoordinator getBpfCoordinator(
416                 BpfCoordinator.Dependencies deps) {
417             return mBpfCoordinator;
418         }
419 
420         @Override
getOffloadHardwareInterface(Handler h, SharedLog log)421         public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
422             return mOffloadHardwareInterface;
423         }
424 
425         @Override
getOffloadController(Handler h, SharedLog log, OffloadController.Dependencies deps)426         public OffloadController getOffloadController(Handler h, SharedLog log,
427                 OffloadController.Dependencies deps) {
428             mOffloadCtrl = spy(super.getOffloadController(h, log, deps));
429             // Return real object here instead of mock because
430             // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object.
431             return mOffloadCtrl;
432         }
433 
434         @Override
getUpstreamNetworkMonitor(Context ctx, StateMachine target, SharedLog log, int what)435         public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx,
436                 StateMachine target, SharedLog log, int what) {
437             // Use a real object instead of a mock so that some tests can use a real UNM and some
438             // can use a mock.
439             mUpstreamNetworkMonitorSM = target;
440             mUpstreamNetworkMonitor = spy(super.getUpstreamNetworkMonitor(ctx, target, log, what));
441             return mUpstreamNetworkMonitor;
442         }
443 
444         @Override
getIPv6TetheringCoordinator( ArrayList<IpServer> notifyList, SharedLog log)445         public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
446                 ArrayList<IpServer> notifyList, SharedLog log) {
447             mIpv6CoordinatorNotifyList = notifyList;
448             return mIPv6TetheringCoordinator;
449         }
450 
451         @Override
getIpServerDependencies()452         public IpServer.Dependencies getIpServerDependencies() {
453             return mIpServerDependencies;
454         }
455 
456         @Override
getEntitlementManager(Context ctx, Handler h, SharedLog log, Runnable callback)457         public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log,
458                 Runnable callback) {
459             mEntitleMgr = spy(super.getEntitlementManager(ctx, h, log, callback));
460             return mEntitleMgr;
461         }
462 
463         @Override
generateTetheringConfiguration(Context ctx, SharedLog log, int subId)464         public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
465                 int subId) {
466             mConfig = spy(new FakeTetheringConfiguration(ctx, log, subId));
467             return mConfig;
468         }
469 
470         @Override
getINetd(Context context)471         public INetd getINetd(Context context) {
472             return mNetd;
473         }
474 
475         @Override
getTetheringLooper()476         public Looper getTetheringLooper() {
477             return mLooper.getLooper();
478         }
479 
480         @Override
getContext()481         public Context getContext() {
482             return mServiceContext;
483         }
484 
485         @Override
getBluetoothAdapter()486         public BluetoothAdapter getBluetoothAdapter() {
487             return mBluetoothAdapter;
488         }
489 
490         @Override
getNotificationUpdater(Context ctx, Looper looper)491         public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) {
492             return mNotificationUpdater;
493         }
494 
495         @Override
isTetheringDenied()496         public boolean isTetheringDenied() {
497             return false;
498         }
499 
500         @Override
getPrivateAddressCoordinator(Context ctx, TetheringConfiguration cfg)501         public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx,
502                 TetheringConfiguration cfg) {
503             mPrivateAddressCoordinator = super.getPrivateAddressCoordinator(ctx, cfg);
504             return mPrivateAddressCoordinator;
505         }
506 
507         @Override
getBluetoothPanShim(BluetoothPan pan)508         public BluetoothPanShim getBluetoothPanShim(BluetoothPan pan) {
509             try {
510                 when(mBluetoothPanShim.requestTetheredInterface(
511                         any(), any())).thenReturn(mTetheredInterfaceRequestShim);
512             } catch (UnsupportedApiLevelException e) {
513                 fail("BluetoothPan#requestTetheredInterface is not supported");
514             }
515             return mBluetoothPanShim;
516         }
517     }
518 
buildUpstreamLinkProperties(String interfaceName, boolean withIPv4, boolean withIPv6, boolean with464xlat)519     private static LinkProperties buildUpstreamLinkProperties(String interfaceName,
520             boolean withIPv4, boolean withIPv6, boolean with464xlat) {
521         final LinkProperties prop = new LinkProperties();
522         prop.setInterfaceName(interfaceName);
523 
524         if (withIPv4) {
525             prop.addLinkAddress(new LinkAddress("10.1.2.3/15"));
526             prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
527                     InetAddresses.parseNumericAddress("10.0.0.1"),
528                     interfaceName, RTN_UNICAST));
529         }
530 
531         if (withIPv6) {
532             prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2"));
533             prop.addLinkAddress(
534                     new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
535                             NetworkConstants.RFC7421_PREFIX_LENGTH));
536             prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
537                     InetAddresses.parseNumericAddress("2001:db8::1"),
538                     interfaceName, RTN_UNICAST));
539         }
540 
541         if (with464xlat) {
542             final String clatInterface = "v4-" + interfaceName;
543             final LinkProperties stackedLink = new LinkProperties();
544             stackedLink.setInterfaceName(clatInterface);
545             stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
546                     InetAddresses.parseNumericAddress("192.0.0.1"),
547                     clatInterface, RTN_UNICAST));
548 
549             prop.addStackedLink(stackedLink);
550         }
551 
552         return prop;
553     }
554 
buildUpstreamCapabilities(int transport, int... otherCaps)555     private static NetworkCapabilities buildUpstreamCapabilities(int transport, int... otherCaps) {
556         // TODO: add NOT_VCN_MANAGED.
557         final NetworkCapabilities nc = new NetworkCapabilities()
558                 .addTransportType(transport);
559         for (int cap : otherCaps) {
560             nc.addCapability(cap);
561         }
562         return nc;
563     }
564 
buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, boolean with464xlat)565     private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4,
566             boolean withIPv6, boolean with464xlat) {
567         return new UpstreamNetworkState(
568                 buildUpstreamLinkProperties(TEST_MOBILE_IFNAME, withIPv4, withIPv6, with464xlat),
569                 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_INTERNET),
570                 new Network(CELLULAR_NETID));
571     }
572 
buildMobileIPv4UpstreamState()573     private static UpstreamNetworkState buildMobileIPv4UpstreamState() {
574         return buildMobileUpstreamState(true, false, false);
575     }
576 
buildMobileIPv6UpstreamState()577     private static UpstreamNetworkState buildMobileIPv6UpstreamState() {
578         return buildMobileUpstreamState(false, true, false);
579     }
580 
buildMobileDualStackUpstreamState()581     private static UpstreamNetworkState buildMobileDualStackUpstreamState() {
582         return buildMobileUpstreamState(true, true, false);
583     }
584 
buildMobile464xlatUpstreamState()585     private static UpstreamNetworkState buildMobile464xlatUpstreamState() {
586         return buildMobileUpstreamState(false, true, true);
587     }
588 
buildWifiUpstreamState()589     private static UpstreamNetworkState buildWifiUpstreamState() {
590         return new UpstreamNetworkState(
591                 buildUpstreamLinkProperties(TEST_WIFI_IFNAME, true /* IPv4 */, true /* IPv6 */,
592                         false /* 464xlat */),
593                 buildUpstreamCapabilities(TRANSPORT_WIFI, NET_CAPABILITY_INTERNET),
594                 new Network(WIFI_NETID));
595     }
596 
buildDunUpstreamState()597     private static UpstreamNetworkState buildDunUpstreamState() {
598         return new UpstreamNetworkState(
599                 buildUpstreamLinkProperties(TEST_DUN_IFNAME, true /* IPv4 */, true /* IPv6 */,
600                         false /* 464xlat */),
601                 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_DUN),
602                 new Network(DUN_NETID));
603     }
604 
605     // See FakeSettingsProvider#clearSettingsProvider() that this also needs to be called before
606     // use.
607     @BeforeClass
setupOnce()608     public static void setupOnce() {
609         FakeSettingsProvider.clearSettingsProvider();
610     }
611 
612     @Before
setUp()613     public void setUp() throws Exception {
614         MockitoAnnotations.initMocks(this);
615         when(mResources.getStringArray(R.array.config_tether_dhcp_range))
616                 .thenReturn(new String[0]);
617         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
618                 false);
619         when(mNetd.interfaceGetList())
620                 .thenReturn(new String[] {
621                         TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_RNDIS_IFNAME, TEST_P2P_IFNAME,
622                         TEST_NCM_IFNAME, TEST_ETH_IFNAME, TEST_BT_IFNAME});
623         when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn("");
624         mInterfaceConfiguration = new InterfaceConfigurationParcel();
625         mInterfaceConfiguration.flags = new String[0];
626         when(mRouterAdvertisementDaemon.start())
627                 .thenReturn(true);
628         initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
629                 0 /* defaultDisabled */);
630         when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats);
631 
632         mServiceContext = new TestContext(mContext);
633         mServiceContext.setUseRegisteredHandlers(true);
634         mContentResolver = new MockContentResolver(mServiceContext);
635         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
636         setTetheringSupported(true /* supported */);
637         mIntents = new Vector<>();
638         mBroadcastReceiver = new BroadcastReceiver() {
639             @Override
640             public void onReceive(Context context, Intent intent) {
641                 mIntents.addElement(intent);
642             }
643         };
644         mServiceContext.registerReceiver(mBroadcastReceiver,
645                 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
646 
647         mCm = spy(new TestConnectivityManager(mServiceContext, mock(IConnectivityManager.class)));
648 
649         mTethering = makeTethering();
650         verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
651         verify(mNetd).registerUnsolicitedEventListener(any());
652         verifyDefaultNetworkRequestFiled();
653 
654         final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
655                 ArgumentCaptor.forClass(PhoneStateListener.class);
656         verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
657                 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
658         mPhoneStateListener = phoneListenerCaptor.getValue();
659 
660         final ArgumentCaptor<SoftApCallback> softApCallbackCaptor =
661                 ArgumentCaptor.forClass(SoftApCallback.class);
662         verify(mWifiManager).registerSoftApCallback(any(), softApCallbackCaptor.capture());
663         mSoftApCallback = softApCallbackCaptor.getValue();
664 
665         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
666         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
667     }
668 
setTetheringSupported(final boolean supported)669     private void setTetheringSupported(final boolean supported) {
670         Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED,
671                 supported ? 1 : 0);
672         when(mUserManager.hasUserRestriction(
673                 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported);
674         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
675                 TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION);
676         // Setup tetherable configuration.
677         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
678                 .thenReturn(new String[] {TEST_RNDIS_REGEX});
679         when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
680                 .thenReturn(new String[] {TEST_WIFI_REGEX});
681         when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
682                 .thenReturn(new String[] {TEST_P2P_REGEX});
683         when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
684                 .thenReturn(new String[] {TEST_BT_REGEX});
685         when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
686                 .thenReturn(new String[] {TEST_NCM_REGEX});
687         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)).thenReturn(true);
688         when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
689                 new int[] {TYPE_WIFI, TYPE_MOBILE_DUN});
690         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
691     }
692 
initTetheringUpstream(UpstreamNetworkState upstreamState)693     private void initTetheringUpstream(UpstreamNetworkState upstreamState) {
694         doReturn(upstreamState).when(mUpstreamNetworkMonitor).getCurrentPreferredUpstream();
695         doReturn(upstreamState).when(mUpstreamNetworkMonitor).selectPreferredUpstreamType(any());
696     }
697 
makeTethering()698     private Tethering makeTethering() {
699         return new Tethering(mTetheringDependencies);
700     }
701 
createTetheringRequestParcel(final int type)702     private TetheringRequestParcel createTetheringRequestParcel(final int type) {
703         return createTetheringRequestParcel(type, null, null, false, CONNECTIVITY_SCOPE_GLOBAL);
704     }
705 
createTetheringRequestParcel(final int type, final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt, final int scope)706     private TetheringRequestParcel createTetheringRequestParcel(final int type,
707             final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt,
708             final int scope) {
709         final TetheringRequestParcel request = new TetheringRequestParcel();
710         request.tetheringType = type;
711         request.localIPv4Address = serverAddr;
712         request.staticClientAddress = clientAddr;
713         request.exemptFromEntitlementCheck = exempt;
714         request.showProvisioningUi = false;
715         request.connectivityScope = scope;
716 
717         return request;
718     }
719 
720     @After
tearDown()721     public void tearDown() {
722         mServiceContext.unregisterReceiver(mBroadcastReceiver);
723         FakeSettingsProvider.clearSettingsProvider();
724     }
725 
sendWifiApStateChanged(int state)726     private void sendWifiApStateChanged(int state) {
727         final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
728         intent.putExtra(EXTRA_WIFI_AP_STATE, state);
729         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
730         mLooper.dispatchAll();
731     }
732 
sendWifiApStateChanged(int state, String ifname, int ipmode)733     private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
734         final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
735         intent.putExtra(EXTRA_WIFI_AP_STATE, state);
736         intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
737         intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
738         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
739         mLooper.dispatchAll();
740     }
741 
742     private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = {
743             android.Manifest.permission.ACCESS_FINE_LOCATION,
744             android.Manifest.permission.ACCESS_WIFI_STATE
745     };
746 
sendWifiP2pConnectionChanged( boolean isGroupFormed, boolean isGroupOwner, String ifname)747     private void sendWifiP2pConnectionChanged(
748             boolean isGroupFormed, boolean isGroupOwner, String ifname) {
749         WifiP2pGroup group = null;
750         WifiP2pInfo p2pInfo = new WifiP2pInfo();
751         p2pInfo.groupFormed = isGroupFormed;
752         if (isGroupFormed) {
753             p2pInfo.isGroupOwner = isGroupOwner;
754             group = mock(WifiP2pGroup.class);
755             when(group.isGroupOwner()).thenReturn(isGroupOwner);
756             when(group.getInterface()).thenReturn(ifname);
757         }
758 
759         final Intent intent = mock(Intent.class);
760         when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
761         when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo);
762         when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group);
763 
764         mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
765                 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST);
766         mLooper.dispatchAll();
767     }
768 
769     // enableType:
770     // No function enabled            = -1
771     // TETHER_USB_RNDIS_FUNCTION      = 0
772     // TETHER_USB_NCM_FUNCTIONS       = 1
773     // TETHER_USB_RNDIS_NCM_FUNCTIONS = 2
tetherUsbFunctionMatches(int function, int enabledType)774     private boolean tetherUsbFunctionMatches(int function, int enabledType) {
775         if (enabledType < 0) return false;
776 
777         if (enabledType == TETHER_USB_RNDIS_NCM_FUNCTIONS) return function < enabledType;
778 
779         return function == enabledType;
780     }
781 
sendUsbBroadcast(boolean connected, boolean configured, int function)782     private void sendUsbBroadcast(boolean connected, boolean configured, int function) {
783         final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
784         intent.putExtra(USB_CONNECTED, connected);
785         intent.putExtra(USB_CONFIGURED, configured);
786         intent.putExtra(USB_FUNCTION_RNDIS,
787                 tetherUsbFunctionMatches(TETHER_USB_RNDIS_FUNCTION, function));
788         intent.putExtra(USB_FUNCTION_NCM,
789                 tetherUsbFunctionMatches(TETHER_USB_NCM_FUNCTION, function));
790         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
791         mLooper.dispatchAll();
792     }
793 
sendConfigurationChanged()794     private void sendConfigurationChanged() {
795         final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
796         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
797         mLooper.dispatchAll();
798     }
799 
verifyDefaultNetworkRequestFiled()800     private void verifyDefaultNetworkRequestFiled() {
801         if (isAtLeastS()) {
802             verify(mCm, times(1)).registerSystemDefaultNetworkCallback(
803                     any(NetworkCallback.class), any(Handler.class));
804         } else {
805             ArgumentCaptor<NetworkRequest> reqCaptor = ArgumentCaptor.forClass(
806                     NetworkRequest.class);
807             verify(mCm, times(1)).requestNetwork(reqCaptor.capture(),
808                     any(NetworkCallback.class), any(Handler.class));
809             assertTrue(TestConnectivityManager.looksLikeDefaultRequest(reqCaptor.getValue()));
810         }
811 
812         // The default network request is only ever filed once.
813         verifyNoMoreInteractions(mCm);
814     }
815 
verifyInterfaceServingModeStarted(String ifname)816     private void verifyInterfaceServingModeStarted(String ifname) throws Exception {
817         verify(mNetd, times(1)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
818         verify(mNetd, times(1)).tetherInterfaceAdd(ifname);
819         verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, ifname);
820         verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname),
821                 anyString(), anyString());
822     }
823 
verifyTetheringBroadcast(String ifname, String whichExtra)824     private void verifyTetheringBroadcast(String ifname, String whichExtra) {
825         // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
826         final Intent bcast = mIntents.get(0);
827         assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
828         final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
829         assertTrue(ifnames.contains(ifname));
830         mIntents.remove(bcast);
831     }
832 
failingLocalOnlyHotspotLegacyApBroadcast( boolean emulateInterfaceStatusChanged)833     public void failingLocalOnlyHotspotLegacyApBroadcast(
834             boolean emulateInterfaceStatusChanged) throws Exception {
835         // Emulate externally-visible WifiManager effects, causing the
836         // per-interface state machine to start up, and telling us that
837         // hotspot mode is to be started.
838         if (emulateInterfaceStatusChanged) {
839             mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
840         }
841         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
842 
843         // If, and only if, Tethering received an interface status changed then
844         // it creates a IpServer and sends out a broadcast indicating that the
845         // interface is "available".
846         if (emulateInterfaceStatusChanged) {
847             // There is 1 IpServer state change event: STATE_AVAILABLE
848             verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
849             verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
850             verify(mWifiManager).updateInterfaceIpState(
851                     TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
852         }
853         verifyNoMoreInteractions(mNetd);
854         verifyNoMoreInteractions(mWifiManager);
855     }
856 
prepareNcmTethering()857     private void prepareNcmTethering() {
858         // Emulate startTethering(TETHERING_NCM) called
859         mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null);
860         mLooper.dispatchAll();
861         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
862     }
863 
prepareUsbTethering()864     private void prepareUsbTethering() {
865         // Emulate pressing the USB tethering button in Settings UI.
866         final TetheringRequestParcel request = createTetheringRequestParcel(TETHERING_USB);
867         mTethering.startTethering(request, null);
868         mLooper.dispatchAll();
869 
870         assertEquals(1, mTethering.getActiveTetheringRequests().size());
871         assertEquals(request, mTethering.getActiveTetheringRequests().get(TETHERING_USB));
872 
873         if (mTethering.getTetheringConfiguration().isUsingNcm()) {
874             verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NCM);
875             mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
876         } else {
877             verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
878             mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true);
879         }
880 
881     }
882 
883     @Test
testUsbConfiguredBroadcastStartsTethering()884     public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
885         UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
886         initTetheringUpstream(upstreamState);
887         prepareUsbTethering();
888 
889         // This should produce no activity of any kind.
890         verifyNoMoreInteractions(mNetd);
891 
892         // Pretend we then receive USB configured broadcast.
893         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
894         // Now we should see the start of tethering mechanics (in this case:
895         // tetherMatchingInterfaces() which starts by fetching all interfaces).
896         verify(mNetd, times(1)).interfaceGetList();
897 
898         // UpstreamNetworkMonitor should receive selected upstream
899         verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
900         verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
901     }
902 
903     @Test
failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged()904     public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
905         failingLocalOnlyHotspotLegacyApBroadcast(true);
906     }
907 
908     @Test
failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged()909     public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
910         failingLocalOnlyHotspotLegacyApBroadcast(false);
911     }
912 
workingLocalOnlyHotspotEnrichedApBroadcast( boolean emulateInterfaceStatusChanged)913     public void workingLocalOnlyHotspotEnrichedApBroadcast(
914             boolean emulateInterfaceStatusChanged) throws Exception {
915         // Emulate externally-visible WifiManager effects, causing the
916         // per-interface state machine to start up, and telling us that
917         // hotspot mode is to be started.
918         if (emulateInterfaceStatusChanged) {
919             mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
920         }
921         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
922 
923         verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
924         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
925         verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
926         verify(mNetd, times(1)).tetherStartWithConfiguration(any());
927         verifyNoMoreInteractions(mNetd);
928         verify(mWifiManager).updateInterfaceIpState(
929                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
930         verify(mWifiManager).updateInterfaceIpState(
931                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
932         verifyNoMoreInteractions(mWifiManager);
933         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
934         verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
935         // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
936         verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
937 
938         // Emulate externally-visible WifiManager effects, when hotspot mode
939         // is being torn down.
940         sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
941         mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
942         mLooper.dispatchAll();
943 
944         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
945         verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
946         verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
947         // interfaceSetCfg() called once for enabling and twice disabling IPv4.
948         verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
949         verify(mNetd, times(1)).tetherStop();
950         verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
951         verify(mWifiManager, times(3)).updateInterfaceIpState(
952                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
953         verifyNoMoreInteractions(mNetd);
954         verifyNoMoreInteractions(mWifiManager);
955         // Asking for the last error after the per-interface state machine
956         // has been reaped yields an unknown interface error.
957         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_WLAN_IFNAME));
958     }
959 
960     /**
961      * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
962      */
sendIPv6TetherUpdates(UpstreamNetworkState upstreamState)963     private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) {
964         // IPv6TetheringCoordinator must have been notified of downstream
965         for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) {
966             UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
967             ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
968                     upstreamState.linkProperties.isIpv6Provisioned()
969                             ? ipv6OnlyState.linkProperties
970                             : null);
971             break;
972         }
973         mLooper.dispatchAll();
974     }
975 
runUsbTethering(UpstreamNetworkState upstreamState)976     private void runUsbTethering(UpstreamNetworkState upstreamState) {
977         initTetheringUpstream(upstreamState);
978         prepareUsbTethering();
979         if (mTethering.getTetheringConfiguration().isUsingNcm()) {
980             sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION);
981             verify(mIPv6TetheringCoordinator).addActiveDownstream(
982                     argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_NCM_IFNAME)),
983                     eq(IpServer.STATE_TETHERED));
984         } else {
985             sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
986             verify(mIPv6TetheringCoordinator).addActiveDownstream(
987                     argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_RNDIS_IFNAME)),
988                     eq(IpServer.STATE_TETHERED));
989         }
990 
991     }
992 
assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName)993     private void assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName) {
994         if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME)
995                     || "T".equals(Build.VERSION.CODENAME)) {
996             verify(mDadProxy, times(numOfCalls)).setUpstreamIface(
997                      argThat(ifaceParams  -> ifaceName.equals(ifaceParams.name)));
998         }
999     }
1000 
1001     @Test
workingMobileUsbTethering_IPv4()1002     public void workingMobileUsbTethering_IPv4() throws Exception {
1003         UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1004         runUsbTethering(upstreamState);
1005 
1006         verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1007         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1008 
1009         sendIPv6TetherUpdates(upstreamState);
1010         assertSetIfaceToDadProxy(0 /* numOfCalls */, "" /* ifaceName */);
1011         verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
1012         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1013                 any(), any());
1014     }
1015 
1016     @Test
workingMobileUsbTethering_IPv4LegacyDhcp()1017     public void workingMobileUsbTethering_IPv4LegacyDhcp() {
1018         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
1019                 true);
1020         sendConfigurationChanged();
1021         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1022         runUsbTethering(upstreamState);
1023         sendIPv6TetherUpdates(upstreamState);
1024 
1025         verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
1026     }
1027 
1028     @Test
workingMobileUsbTethering_IPv6()1029     public void workingMobileUsbTethering_IPv6() throws Exception {
1030         UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
1031         runUsbTethering(upstreamState);
1032 
1033         verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1034         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1035 
1036         sendIPv6TetherUpdates(upstreamState);
1037         // TODO: add interfaceParams to compare in verify.
1038         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
1039         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
1040         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1041     }
1042 
1043     @Test
workingMobileUsbTethering_DualStack()1044     public void workingMobileUsbTethering_DualStack() throws Exception {
1045         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
1046         runUsbTethering(upstreamState);
1047 
1048         verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1049         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1050         verify(mRouterAdvertisementDaemon, times(1)).start();
1051         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1052                 any(), any());
1053 
1054         sendIPv6TetherUpdates(upstreamState);
1055         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
1056         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
1057         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1058     }
1059 
1060     @Test
workingMobileUsbTethering_MultipleUpstreams()1061     public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
1062         UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
1063         runUsbTethering(upstreamState);
1064 
1065         verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_XLAT_MOBILE_IFNAME);
1066         verify(mNetd, times(1)).tetherAddForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1067         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1068                 any(), any());
1069         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME,
1070                 TEST_XLAT_MOBILE_IFNAME);
1071         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1072 
1073         sendIPv6TetherUpdates(upstreamState);
1074         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
1075         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
1076         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1077     }
1078 
1079     @Test
workingMobileUsbTethering_v6Then464xlat()1080     public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
1081         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
1082                 TetheringConfiguration.TETHER_USB_NCM_FUNCTION);
1083         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
1084                 .thenReturn(new String[] {TEST_NCM_REGEX});
1085         sendConfigurationChanged();
1086 
1087         // Setup IPv6
1088         UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
1089         runUsbTethering(upstreamState);
1090 
1091         verify(mNetd, times(1)).tetherAddForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME);
1092         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1093                 any(), any());
1094         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME);
1095 
1096         // Then 464xlat comes up
1097         upstreamState = buildMobile464xlatUpstreamState();
1098         initTetheringUpstream(upstreamState);
1099 
1100         // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
1101         mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
1102                 Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
1103                 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
1104                 0,
1105                 upstreamState);
1106         mLooper.dispatchAll();
1107 
1108         // Forwarding is added for 464xlat
1109         verify(mNetd, times(1)).tetherAddForward(TEST_NCM_IFNAME, TEST_XLAT_MOBILE_IFNAME);
1110         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_NCM_IFNAME,
1111                 TEST_XLAT_MOBILE_IFNAME);
1112         // Forwarding was not re-added for v6 (still times(1))
1113         verify(mNetd, times(1)).tetherAddForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME);
1114         verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME);
1115         // DHCP not restarted on downstream (still times(1))
1116         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1117                 any(), any());
1118     }
1119 
1120     @Test
configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes()1121     public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
1122         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
1123         sendConfigurationChanged();
1124 
1125         // Setup IPv6
1126         final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
1127         runUsbTethering(upstreamState);
1128 
1129         // UpstreamNetworkMonitor should choose upstream automatically
1130         // (in this specific case: choose the default network).
1131         verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
1132         verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
1133 
1134         verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
1135     }
1136 
verifyDisableTryCellWhenTetheringStop(InOrder inOrder)1137     private void verifyDisableTryCellWhenTetheringStop(InOrder inOrder) {
1138         runStopUSBTethering();
1139         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1140     }
1141 
upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi)1142     private void upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder,
1143             TestNetworkAgent mobile, TestNetworkAgent wifi) throws Exception {
1144         // Enable automatic upstream selection.
1145         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic);
1146         sendConfigurationChanged();
1147         mLooper.dispatchAll();
1148 
1149         // Start USB tethering with no current upstream.
1150         prepareUsbTethering();
1151         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
1152         inOrder.verify(mUpstreamNetworkMonitor).startObserveAllNetworks();
1153         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1154 
1155         // Pretend cellular connected and expect the upstream to be set.
1156         mobile.fakeConnect();
1157         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST);
1158         mLooper.dispatchAll();
1159         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
1160 
1161         // Switch upstream to wifi.
1162         wifi.fakeConnect();
1163         mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST);
1164         mLooper.dispatchAll();
1165         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1166         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
1167     }
1168 
1169     @Test
testAutomaticUpstreamSelection()1170     public void testAutomaticUpstreamSelection() throws Exception {
1171         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1172         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1173         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1174         // Enable automatic upstream selection.
1175         upstreamSelectionTestCommon(true, inOrder, mobile, wifi);
1176 
1177         // This code has historically been racy, so test different orderings of CONNECTIVITY_ACTION
1178         // broadcasts and callbacks, and add mLooper.dispatchAll() calls between the two.
1179         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1180 
1181         // Switch upstreams a few times.
1182         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll);
1183         mLooper.dispatchAll();
1184         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
1185 
1186         mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST, doDispatchAll);
1187         mLooper.dispatchAll();
1188         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1189         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
1190 
1191         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1192         mLooper.dispatchAll();
1193         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
1194 
1195         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1196         mLooper.dispatchAll();
1197         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1198         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
1199 
1200         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll);
1201         mLooper.dispatchAll();
1202         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
1203 
1204         // Wifi disconnecting should not have any affect since it's not the current upstream.
1205         wifi.fakeDisconnect();
1206         mLooper.dispatchAll();
1207         inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
1208 
1209         // Lose and regain upstream.
1210         assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
1211                 .hasIPv4Address());
1212         mCm.makeDefaultNetwork(null, BROADCAST_FIRST, doDispatchAll);
1213         mLooper.dispatchAll();
1214         mobile.fakeDisconnect();
1215         mLooper.dispatchAll();
1216         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1217         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
1218 
1219         mobile = new TestNetworkAgent(mCm, buildMobile464xlatUpstreamState());
1220         mobile.fakeConnect();
1221         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll);
1222         mLooper.dispatchAll();
1223         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
1224 
1225         // Check the IP addresses to ensure that the upstream is indeed not the same as the previous
1226         // mobile upstream, even though the netId is (unrealistically) the same.
1227         assertFalse(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
1228                 .hasIPv4Address());
1229 
1230         // Lose and regain upstream again.
1231         mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll);
1232         mobile.fakeDisconnect();
1233         mLooper.dispatchAll();
1234         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1235         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
1236 
1237         mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1238         mobile.fakeConnect();
1239         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll);
1240         mLooper.dispatchAll();
1241         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
1242 
1243         assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
1244                 .hasIPv4Address());
1245 
1246         // Check that the code does not crash if onLinkPropertiesChanged is received after onLost.
1247         mobile.fakeDisconnect();
1248         mobile.sendLinkProperties();
1249         mLooper.dispatchAll();
1250 
1251         verifyDisableTryCellWhenTetheringStop(inOrder);
1252     }
1253 
1254     @Test
testLegacyUpstreamSelection()1255     public void testLegacyUpstreamSelection() throws Exception {
1256         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1257         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1258         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1259         // Enable legacy upstream selection.
1260         upstreamSelectionTestCommon(false, inOrder, mobile, wifi);
1261 
1262         // Wifi disconnecting and the default network switch to mobile, the upstream should also
1263         // switch to mobile.
1264         wifi.fakeDisconnect();
1265         mLooper.dispatchAll();
1266         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, null);
1267         mLooper.dispatchAll();
1268         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(mobile.networkId);
1269 
1270         wifi.fakeConnect();
1271         mLooper.dispatchAll();
1272         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST, null);
1273         mLooper.dispatchAll();
1274         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1275         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
1276 
1277         verifyDisableTryCellWhenTetheringStop(inOrder);
1278     }
1279 
1280     @Test
testChooseDunUpstreamByAutomaticMode()1281     public void testChooseDunUpstreamByAutomaticMode() throws Exception {
1282         // Enable automatic upstream selection.
1283         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1284         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1285         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1286         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1287         chooseDunUpstreamTestCommon(true, inOrder, mobile, wifi, dun);
1288 
1289         // When default network switch to mobile and wifi is connected (may have low signal),
1290         // automatic mode would request dun again and choose it as upstream.
1291         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1292         mLooper.dispatchAll();
1293         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1294         ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class);
1295         inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(), any());
1296         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
1297         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1298         dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
1299         mLooper.dispatchAll();
1300         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
1301 
1302         // Lose and regain upstream again.
1303         dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
1304         mLooper.dispatchAll();
1305         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1306         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(null);
1307         inOrder.verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class));
1308         dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
1309         mLooper.dispatchAll();
1310         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
1311 
1312         verifyDisableTryCellWhenTetheringStop(inOrder);
1313     }
1314 
1315     @Test
testChooseDunUpstreamByLegacyMode()1316     public void testChooseDunUpstreamByLegacyMode() throws Exception {
1317         // Enable Legacy upstream selection.
1318         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1319         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1320         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1321         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1322         chooseDunUpstreamTestCommon(false, inOrder, mobile, wifi, dun);
1323 
1324         // Legacy mode would keep use wifi as upstream (because it has higher priority in the
1325         // list).
1326         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1327         mLooper.dispatchAll();
1328         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1329         inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
1330         // BUG: when wifi disconnect, the dun request would not be filed again because wifi is
1331         // no longer be default network which do not have CONNECTIVIY_ACTION broadcast.
1332         wifi.fakeDisconnect();
1333         mLooper.dispatchAll();
1334         inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(),
1335                 any());
1336 
1337         // Change the legacy priority list that dun is higher than wifi.
1338         when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
1339                 new int[] { TYPE_MOBILE_DUN, TYPE_WIFI });
1340         sendConfigurationChanged();
1341         mLooper.dispatchAll();
1342 
1343         // Make wifi as default network. Note: mobile also connected.
1344         wifi.fakeConnect();
1345         mLooper.dispatchAll();
1346         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1347         mLooper.dispatchAll();
1348         // BUG: dun has higher priority than wifi but tethering don't file dun request because
1349         // current upstream is wifi.
1350         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1351         inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(),
1352                 any());
1353 
1354         verifyDisableTryCellWhenTetheringStop(inOrder);
1355     }
1356 
chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun)1357     private void chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder,
1358             TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun) throws Exception {
1359         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic);
1360         when(mTelephonyManager.isTetheringApnRequired()).thenReturn(true);
1361         sendConfigurationChanged();
1362         mLooper.dispatchAll();
1363 
1364         // Start USB tethering with no current upstream.
1365         prepareUsbTethering();
1366         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
1367         inOrder.verify(mUpstreamNetworkMonitor).startObserveAllNetworks();
1368         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1369         ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class);
1370         inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(),
1371                 captor.capture());
1372         final NetworkCallback dunNetworkCallback1 = captor.getValue();
1373 
1374         // Pretend cellular connected and expect the upstream to be set.
1375         mobile.fakeConnect();
1376         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST);
1377         mLooper.dispatchAll();
1378         inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(mobile.networkId);
1379 
1380         // Pretend dun connected and expect choose dun as upstream.
1381         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1382         dun.fakeConnect(BROADCAST_FIRST, doDispatchAll);
1383         mLooper.dispatchAll();
1384         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(dun.networkId);
1385 
1386         // When wifi connected, unregister dun request and choose wifi as upstream.
1387         wifi.fakeConnect();
1388         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1389         mLooper.dispatchAll();
1390         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1391         inOrder.verify(mCm).unregisterNetworkCallback(eq(dunNetworkCallback1));
1392         inOrder.verify(mUpstreamNetworkMonitor).setCurrentUpstream(wifi.networkId);
1393         dun.fakeDisconnect(BROADCAST_FIRST, doDispatchAll);
1394         mLooper.dispatchAll();
1395         inOrder.verify(mUpstreamNetworkMonitor, never()).setCurrentUpstream(any());
1396     }
1397 
runNcmTethering()1398     private void runNcmTethering() {
1399         prepareNcmTethering();
1400         sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION);
1401     }
1402 
1403     @Test
workingNcmTethering()1404     public void workingNcmTethering() throws Exception {
1405         runNcmTethering();
1406 
1407         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1408                 any(), any());
1409     }
1410 
1411     @Test
workingNcmTethering_LegacyDhcp()1412     public void workingNcmTethering_LegacyDhcp() {
1413         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
1414                 true);
1415         sendConfigurationChanged();
1416         runNcmTethering();
1417 
1418         verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
1419     }
1420 
1421     @Test
workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged()1422     public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
1423         workingLocalOnlyHotspotEnrichedApBroadcast(true);
1424     }
1425 
1426     @Test
workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged()1427     public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
1428         workingLocalOnlyHotspotEnrichedApBroadcast(false);
1429     }
1430 
1431     // TODO: Test with and without interfaceStatusChanged().
1432     @Test
failingWifiTetheringLegacyApBroadcast()1433     public void failingWifiTetheringLegacyApBroadcast() throws Exception {
1434         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
1435 
1436         // Emulate pressing the WiFi tethering button.
1437         mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
1438         mLooper.dispatchAll();
1439         verify(mWifiManager, times(1)).startTetheredHotspot(null);
1440         verifyNoMoreInteractions(mWifiManager);
1441         verifyNoMoreInteractions(mNetd);
1442 
1443         // Emulate externally-visible WifiManager effects, causing the
1444         // per-interface state machine to start up, and telling us that
1445         // tethering mode is to be started.
1446         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1447         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
1448 
1449         // There is 1 IpServer state change event: STATE_AVAILABLE
1450         verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
1451         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
1452         verify(mWifiManager).updateInterfaceIpState(
1453                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1454         verifyNoMoreInteractions(mNetd);
1455         verifyNoMoreInteractions(mWifiManager);
1456     }
1457 
1458     // TODO: Test with and without interfaceStatusChanged().
1459     @Test
workingWifiTetheringEnrichedApBroadcast()1460     public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
1461         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
1462 
1463         // Emulate pressing the WiFi tethering button.
1464         mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
1465         mLooper.dispatchAll();
1466         verify(mWifiManager, times(1)).startTetheredHotspot(null);
1467         verifyNoMoreInteractions(mWifiManager);
1468         verifyNoMoreInteractions(mNetd);
1469 
1470         // Emulate externally-visible WifiManager effects, causing the
1471         // per-interface state machine to start up, and telling us that
1472         // tethering mode is to be started.
1473         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1474         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1475 
1476         verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME);
1477         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
1478         verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
1479         verify(mNetd, times(1)).tetherStartWithConfiguration(any());
1480         verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
1481                 anyString(), anyString());
1482         verifyNoMoreInteractions(mNetd);
1483         verify(mWifiManager).updateInterfaceIpState(
1484                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1485         verify(mWifiManager).updateInterfaceIpState(
1486                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
1487         verifyNoMoreInteractions(mWifiManager);
1488         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
1489         verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
1490         // In tethering mode, in the default configuration, an explicit request
1491         // for a mobile network is also made.
1492         verify(mUpstreamNetworkMonitor, times(1)).setTryCell(true);
1493         // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED
1494         verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
1495         verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
1496 
1497         /////
1498         // We do not currently emulate any upstream being found.
1499         //
1500         // This is why there are no calls to verify mNetd.tetherAddForward() or
1501         // mNetd.ipfwdAddInterfaceForward().
1502         /////
1503 
1504         // Emulate pressing the WiFi tethering button.
1505         mTethering.stopTethering(TETHERING_WIFI);
1506         mLooper.dispatchAll();
1507         verify(mWifiManager, times(1)).stopSoftAp();
1508         verifyNoMoreInteractions(mWifiManager);
1509         verifyNoMoreInteractions(mNetd);
1510 
1511         // Emulate externally-visible WifiManager effects, when tethering mode
1512         // is being torn down.
1513         sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1514         mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
1515         mLooper.dispatchAll();
1516 
1517         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1518         verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
1519         verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1520         // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
1521         verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1522         verify(mNetd, times(1)).tetherStop();
1523         verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
1524         verify(mWifiManager, times(3)).updateInterfaceIpState(
1525                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1526         verifyNoMoreInteractions(mNetd);
1527         verifyNoMoreInteractions(mWifiManager);
1528         // Asking for the last error after the per-interface state machine
1529         // has been reaped yields an unknown interface error.
1530         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_WLAN_IFNAME));
1531     }
1532 
1533     // TODO: Test with and without interfaceStatusChanged().
1534     @Test
failureEnablingIpForwarding()1535     public void failureEnablingIpForwarding() throws Exception {
1536         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
1537         doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
1538 
1539         // Emulate pressing the WiFi tethering button.
1540         mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
1541         mLooper.dispatchAll();
1542         verify(mWifiManager, times(1)).startTetheredHotspot(null);
1543         verifyNoMoreInteractions(mWifiManager);
1544         verifyNoMoreInteractions(mNetd);
1545 
1546         // Emulate externally-visible WifiManager effects, causing the
1547         // per-interface state machine to start up, and telling us that
1548         // tethering mode is to be started.
1549         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1550         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1551 
1552         // We verify get/set called three times here: twice for setup and once during
1553         // teardown because all events happen over the course of the single
1554         // dispatchAll() above. Note that once the IpServer IPv4 address config
1555         // code is refactored the two calls during shutdown will revert to one.
1556         verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
1557         verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME);
1558         verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1559         verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
1560                 anyString(), anyString());
1561         verify(mWifiManager).updateInterfaceIpState(
1562                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1563         verify(mWifiManager).updateInterfaceIpState(
1564                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
1565         // There are 3 IpServer state change event:
1566         //         STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE.
1567         verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
1568         verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
1569         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
1570         // This is called, but will throw.
1571         verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
1572         // This never gets called because of the exception thrown above.
1573         verify(mNetd, times(0)).tetherStartWithConfiguration(any());
1574         // When the main state machine transitions to an error state it tells
1575         // downstream interfaces, which causes us to tell Wi-Fi about the error
1576         // so it can take down AP mode.
1577         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1578         verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
1579         verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1580         verify(mWifiManager).updateInterfaceIpState(
1581                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
1582 
1583         verifyNoMoreInteractions(mWifiManager);
1584         verifyNoMoreInteractions(mNetd);
1585     }
1586 
makeUserRestrictionActionListener( final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow)1587     private UserRestrictionActionListener makeUserRestrictionActionListener(
1588             final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow) {
1589         final Bundle newRestrictions = new Bundle();
1590         newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
1591         when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
1592 
1593         final UserRestrictionActionListener ural =
1594                 new UserRestrictionActionListener(mUserManager, tethering, mNotificationUpdater);
1595         ural.mDisallowTethering = currentDisallow;
1596         return ural;
1597     }
1598 
runUserRestrictionsChange( boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, int expectedInteractionsWithShowNotification)1599     private void runUserRestrictionsChange(
1600             boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive,
1601             int expectedInteractionsWithShowNotification) throws  Exception {
1602         final Tethering mockTethering = mock(Tethering.class);
1603         when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive);
1604 
1605         final UserRestrictionActionListener ural =
1606                 makeUserRestrictionActionListener(mockTethering, currentDisallow, nextDisallow);
1607         ural.onUserRestrictionsChanged();
1608 
1609         verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
1610                 .notifyTetheringDisabledByRestriction();
1611         verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll();
1612     }
1613 
1614     @Test
testDisallowTetheringWhenTetheringIsNotActive()1615     public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception {
1616         final boolean isTetheringActive = false;
1617         final boolean currDisallow = false;
1618         final boolean nextDisallow = true;
1619         final int expectedInteractionsWithShowNotification = 0;
1620 
1621         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
1622                 expectedInteractionsWithShowNotification);
1623     }
1624 
1625     @Test
testDisallowTetheringWhenTetheringIsActive()1626     public void testDisallowTetheringWhenTetheringIsActive() throws Exception {
1627         final boolean isTetheringActive = true;
1628         final boolean currDisallow = false;
1629         final boolean nextDisallow = true;
1630         final int expectedInteractionsWithShowNotification = 1;
1631 
1632         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
1633                 expectedInteractionsWithShowNotification);
1634     }
1635 
1636     @Test
testAllowTetheringWhenTetheringIsNotActive()1637     public void testAllowTetheringWhenTetheringIsNotActive() throws Exception {
1638         final boolean isTetheringActive = false;
1639         final boolean currDisallow = true;
1640         final boolean nextDisallow = false;
1641         final int expectedInteractionsWithShowNotification = 0;
1642 
1643         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
1644                 expectedInteractionsWithShowNotification);
1645     }
1646 
1647     @Test
testAllowTetheringWhenTetheringIsActive()1648     public void testAllowTetheringWhenTetheringIsActive() throws Exception {
1649         final boolean isTetheringActive = true;
1650         final boolean currDisallow = true;
1651         final boolean nextDisallow = false;
1652         final int expectedInteractionsWithShowNotification = 0;
1653 
1654         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
1655                 expectedInteractionsWithShowNotification);
1656     }
1657 
1658     @Test
testDisallowTetheringUnchanged()1659     public void testDisallowTetheringUnchanged() throws Exception {
1660         final boolean isTetheringActive = true;
1661         final int expectedInteractionsWithShowNotification = 0;
1662         boolean currDisallow = true;
1663         boolean nextDisallow = true;
1664 
1665         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
1666                 expectedInteractionsWithShowNotification);
1667 
1668         currDisallow = false;
1669         nextDisallow = false;
1670 
1671         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
1672                 expectedInteractionsWithShowNotification);
1673     }
1674 
1675     @Test
testUntetherUsbWhenRestrictionIsOn()1676     public void testUntetherUsbWhenRestrictionIsOn() {
1677         // Start usb tethering and check that usb interface is tethered.
1678         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1679         runUsbTethering(upstreamState);
1680         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
1681         assertTrue(mTethering.isTetheringActive());
1682         assertEquals(0, mTethering.getActiveTetheringRequests().size());
1683 
1684         final Tethering.UserRestrictionActionListener ural = makeUserRestrictionActionListener(
1685                 mTethering, false /* currentDisallow */, true /* nextDisallow */);
1686 
1687         ural.onUserRestrictionsChanged();
1688         mLooper.dispatchAll();
1689 
1690         // Verify that restriction notification has showed to user.
1691         verify(mNotificationUpdater, times(1)).notifyTetheringDisabledByRestriction();
1692         // Verify that usb tethering has been disabled.
1693         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1694     }
1695 
1696     private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
1697         private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
1698         private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
1699                 new ArrayList<>();
1700         private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>();
1701         private final ArrayList<Integer> mOffloadStatus = new ArrayList<>();
1702         private final ArrayList<List<TetheredClient>> mTetheredClients = new ArrayList<>();
1703         private final ArrayList<Long> mSupportedBitmaps = new ArrayList<>();
1704 
1705         // This function will remove the recorded callbacks, so it must be called once for
1706         // each callback. If this is called after multiple callback, the order matters.
1707         // onCallbackCreated counts as the first call to expectUpstreamChanged with
1708         // @see onCallbackCreated.
expectUpstreamChanged(Network... networks)1709         public void expectUpstreamChanged(Network... networks) {
1710             if (networks == null) {
1711                 assertNoUpstreamChangeCallback();
1712                 return;
1713             }
1714 
1715             final ArrayList<Network> expectedUpstreams =
1716                     new ArrayList<Network>(Arrays.asList(networks));
1717             for (Network upstream : expectedUpstreams) {
1718                 // throws OOB if no expectations
1719                 assertEquals(mActualUpstreams.remove(0), upstream);
1720             }
1721             assertNoUpstreamChangeCallback();
1722         }
1723 
1724         // This function will remove the recorded callbacks, so it must be called once
1725         // for each callback. If this is called after multiple callback, the order matters.
1726         // onCallbackCreated counts as the first call to onConfigurationChanged with
1727         // @see onCallbackCreated.
expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs)1728         public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) {
1729             final ArrayList<TetheringConfigurationParcel> expectedTetherConfig =
1730                     new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs));
1731             for (TetheringConfigurationParcel config : expectedTetherConfig) {
1732                 // throws OOB if no expectations
1733                 final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0);
1734                 assertTetherConfigParcelEqual(actualConfig, config);
1735             }
1736             assertNoConfigChangeCallback();
1737         }
1738 
expectOffloadStatusChanged(final int expectedStatus)1739         public void expectOffloadStatusChanged(final int expectedStatus) {
1740             assertOffloadStatusChangedCallback();
1741             assertEquals(mOffloadStatus.remove(0), new Integer(expectedStatus));
1742         }
1743 
pollTetherStatesChanged()1744         public TetherStatesParcel pollTetherStatesChanged() {
1745             assertStateChangeCallback();
1746             return mTetherStates.remove(0);
1747         }
1748 
expectTetheredClientChanged(List<TetheredClient> leases)1749         public void expectTetheredClientChanged(List<TetheredClient> leases) {
1750             assertFalse(mTetheredClients.isEmpty());
1751             final List<TetheredClient> result = mTetheredClients.remove(0);
1752             assertEquals(leases.size(), result.size());
1753             assertTrue(leases.containsAll(result));
1754         }
1755 
expectSupportedTetheringTypes(Set<Integer> expectedTypes)1756         public void expectSupportedTetheringTypes(Set<Integer> expectedTypes) {
1757             assertEquals(expectedTypes, TetheringManager.unpackBits(mSupportedBitmaps.remove(0)));
1758         }
1759 
1760         @Override
onUpstreamChanged(Network network)1761         public void onUpstreamChanged(Network network) {
1762             mActualUpstreams.add(network);
1763         }
1764 
1765         @Override
onConfigurationChanged(TetheringConfigurationParcel config)1766         public void onConfigurationChanged(TetheringConfigurationParcel config) {
1767             mTetheringConfigs.add(config);
1768         }
1769 
1770         @Override
onTetherStatesChanged(TetherStatesParcel states)1771         public void onTetherStatesChanged(TetherStatesParcel states) {
1772             mTetherStates.add(states);
1773         }
1774 
1775         @Override
onTetherClientsChanged(List<TetheredClient> clients)1776         public void onTetherClientsChanged(List<TetheredClient> clients) {
1777             mTetheredClients.add(clients);
1778         }
1779 
1780         @Override
onOffloadStatusChanged(final int status)1781         public void onOffloadStatusChanged(final int status) {
1782             mOffloadStatus.add(status);
1783         }
1784 
1785         @Override
onCallbackStarted(TetheringCallbackStartedParcel parcel)1786         public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
1787             mActualUpstreams.add(parcel.upstreamNetwork);
1788             mTetheringConfigs.add(parcel.config);
1789             mTetherStates.add(parcel.states);
1790             mOffloadStatus.add(parcel.offloadStatus);
1791             mTetheredClients.add(parcel.tetheredClients);
1792             mSupportedBitmaps.add(parcel.supportedTypes);
1793         }
1794 
1795         @Override
onCallbackStopped(int errorCode)1796         public void onCallbackStopped(int errorCode) { }
1797 
1798         @Override
onSupportedTetheringTypes(long supportedBitmap)1799         public void onSupportedTetheringTypes(long supportedBitmap) {
1800             mSupportedBitmaps.add(supportedBitmap);
1801         }
1802 
assertNoUpstreamChangeCallback()1803         public void assertNoUpstreamChangeCallback() {
1804             assertTrue(mActualUpstreams.isEmpty());
1805         }
1806 
assertNoConfigChangeCallback()1807         public void assertNoConfigChangeCallback() {
1808             assertTrue(mTetheringConfigs.isEmpty());
1809         }
1810 
assertNoStateChangeCallback()1811         public void assertNoStateChangeCallback() {
1812             assertTrue(mTetherStates.isEmpty());
1813         }
1814 
assertStateChangeCallback()1815         public void assertStateChangeCallback() {
1816             assertFalse(mTetherStates.isEmpty());
1817         }
1818 
assertOffloadStatusChangedCallback()1819         public void assertOffloadStatusChangedCallback() {
1820             assertFalse(mOffloadStatus.isEmpty());
1821         }
1822 
assertNoCallback()1823         public void assertNoCallback() {
1824             assertNoUpstreamChangeCallback();
1825             assertNoConfigChangeCallback();
1826             assertNoStateChangeCallback();
1827             assertTrue(mTetheredClients.isEmpty());
1828         }
1829 
assertTetherConfigParcelEqual(@onNull TetheringConfigurationParcel actual, @NonNull TetheringConfigurationParcel expect)1830         private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
1831                 @NonNull TetheringConfigurationParcel expect) {
1832             assertEquals(actual.subId, expect.subId);
1833             assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs);
1834             assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs);
1835             assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs);
1836             assertEquals(actual.isDunRequired, expect.isDunRequired);
1837             assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically);
1838             assertArrayEquals(actual.preferredUpstreamIfaceTypes,
1839                     expect.preferredUpstreamIfaceTypes);
1840             assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges);
1841             assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS);
1842             assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer);
1843             assertArrayEquals(actual.provisioningApp, expect.provisioningApp);
1844             assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi);
1845             assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod);
1846         }
1847     }
1848 
assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel)1849     private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) {
1850         assertFalse(parcel == null);
1851         assertEquals(0, parcel.availableList.length);
1852         assertEquals(0, parcel.tetheredList.length);
1853         assertEquals(0, parcel.localOnlyList.length);
1854         assertEquals(0, parcel.erroredIfaceList.length);
1855         assertEquals(0, parcel.lastErrorList.length);
1856         MiscAsserts.assertFieldCountEquals(5, TetherStatesParcel.class);
1857     }
1858 
1859     @Test
testRegisterTetheringEventCallback()1860     public void testRegisterTetheringEventCallback() throws Exception {
1861         TestTetheringEventCallback callback = new TestTetheringEventCallback();
1862         TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
1863         final TetheringInterface wifiIface = new TetheringInterface(
1864                 TETHERING_WIFI, TEST_WLAN_IFNAME);
1865 
1866         // 1. Register one callback before running any tethering.
1867         mTethering.registerTetheringEventCallback(callback);
1868         mLooper.dispatchAll();
1869         callback.expectTetheredClientChanged(Collections.emptyList());
1870         callback.expectUpstreamChanged(new Network[] {null});
1871         callback.expectConfigurationChanged(
1872                 mTethering.getTetheringConfiguration().toStableParcelable());
1873         TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
1874         assertTetherStatesNotNullButEmpty(tetherState);
1875         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1876         // 2. Enable wifi tethering.
1877         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
1878         initTetheringUpstream(upstreamState);
1879         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
1880         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1881         mLooper.dispatchAll();
1882         tetherState = callback.pollTetherStatesChanged();
1883         assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
1884 
1885         mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null);
1886         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
1887         tetherState = callback.pollTetherStatesChanged();
1888         assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface});
1889         callback.expectUpstreamChanged(upstreamState.network);
1890         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
1891 
1892         // 3. Register second callback.
1893         mTethering.registerTetheringEventCallback(callback2);
1894         mLooper.dispatchAll();
1895         callback2.expectTetheredClientChanged(Collections.emptyList());
1896         callback2.expectUpstreamChanged(upstreamState.network);
1897         callback2.expectConfigurationChanged(
1898                 mTethering.getTetheringConfiguration().toStableParcelable());
1899         tetherState = callback2.pollTetherStatesChanged();
1900         assertEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface});
1901         callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
1902 
1903         // 4. Unregister first callback and disable wifi tethering
1904         mTethering.unregisterTetheringEventCallback(callback);
1905         mLooper.dispatchAll();
1906         mTethering.stopTethering(TETHERING_WIFI);
1907         sendWifiApStateChanged(WIFI_AP_STATE_DISABLED);
1908         if (isAtLeastT()) {
1909             // After T, tethering doesn't support WIFI_AP_STATE_DISABLED with null interface name.
1910             callback2.assertNoStateChangeCallback();
1911             sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME,
1912                     IFACE_IP_MODE_TETHERED);
1913         }
1914         tetherState = callback2.pollTetherStatesChanged();
1915         assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
1916         mLooper.dispatchAll();
1917         callback2.expectUpstreamChanged(new Network[] {null});
1918         callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1919         callback.assertNoCallback();
1920     }
1921 
1922     @Test
testReportFailCallbackIfOffloadNotSupported()1923     public void testReportFailCallbackIfOffloadNotSupported() throws Exception {
1924         final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
1925         TestTetheringEventCallback callback = new TestTetheringEventCallback();
1926         mTethering.registerTetheringEventCallback(callback);
1927         mLooper.dispatchAll();
1928         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1929 
1930         // 1. Offload fail if no OffloadConfig.
1931         initOffloadConfiguration(false /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
1932                 0 /* defaultDisabled */);
1933         runUsbTethering(upstreamState);
1934         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1935         runStopUSBTethering();
1936         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1937         reset(mUsbManager, mIPv6TetheringCoordinator);
1938         // 2. Offload fail if no OffloadControl.
1939         initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_NONE,
1940                 0 /* defaultDisabled */);
1941         runUsbTethering(upstreamState);
1942         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1943         runStopUSBTethering();
1944         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1945         reset(mUsbManager, mIPv6TetheringCoordinator);
1946         // 3. Offload fail if disabled by settings.
1947         initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
1948                 1 /* defaultDisabled */);
1949         runUsbTethering(upstreamState);
1950         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
1951         runStopUSBTethering();
1952         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
1953     }
1954 
runStopUSBTethering()1955     private void runStopUSBTethering() {
1956         mTethering.stopTethering(TETHERING_USB);
1957         mLooper.dispatchAll();
1958         sendUsbBroadcast(true, true, -1 /* function */);
1959         mLooper.dispatchAll();
1960         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
1961     }
1962 
initOffloadConfiguration(final boolean offloadConfig, @OffloadHardwareInterface.OffloadHalVersion final int offloadControlVersion, final int defaultDisabled)1963     private void initOffloadConfiguration(final boolean offloadConfig,
1964             @OffloadHardwareInterface.OffloadHalVersion final int offloadControlVersion,
1965             final int defaultDisabled) {
1966         when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig);
1967         when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControlVersion);
1968         when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn(
1969                 defaultDisabled);
1970     }
1971 
1972     @Test
testMultiSimAware()1973     public void testMultiSimAware() throws Exception {
1974         final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
1975         assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId);
1976 
1977         final int fakeSubId = 1234;
1978         mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
1979         final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
1980         assertEquals(fakeSubId, newConfig.activeDataSubId);
1981         verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId));
1982     }
1983 
1984     @Test
testNoDuplicatedEthernetRequest()1985     public void testNoDuplicatedEthernetRequest() throws Exception {
1986         final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
1987         when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
1988         mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
1989         mLooper.dispatchAll();
1990         verify(mEm, times(1)).requestTetheredInterface(any(), any());
1991         mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
1992         mLooper.dispatchAll();
1993         verifyNoMoreInteractions(mEm);
1994         mTethering.stopTethering(TETHERING_ETHERNET);
1995         mLooper.dispatchAll();
1996         verify(mockRequest, times(1)).release();
1997         mTethering.stopTethering(TETHERING_ETHERNET);
1998         mLooper.dispatchAll();
1999         verifyNoMoreInteractions(mEm);
2000     }
2001 
workingWifiP2pGroupOwner( boolean emulateInterfaceStatusChanged)2002     private void workingWifiP2pGroupOwner(
2003             boolean emulateInterfaceStatusChanged) throws Exception {
2004         if (emulateInterfaceStatusChanged) {
2005             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
2006         }
2007         sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
2008 
2009         verifyInterfaceServingModeStarted(TEST_P2P_IFNAME);
2010         verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
2011         verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
2012         verify(mNetd, times(1)).tetherStartWithConfiguration(any());
2013         verifyNoMoreInteractions(mNetd);
2014         verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
2015         verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
2016         // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
2017         verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
2018 
2019         assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
2020 
2021         // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
2022         // is being removed.
2023         sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME);
2024         mTethering.interfaceRemoved(TEST_P2P_IFNAME);
2025 
2026         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
2027         verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME);
2028         verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
2029         // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
2030         verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
2031         verify(mNetd, times(1)).tetherStop();
2032         verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
2033         verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
2034         verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
2035         verifyNoMoreInteractions(mNetd);
2036         // Asking for the last error after the per-interface state machine
2037         // has been reaped yields an unknown interface error.
2038         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
2039     }
2040 
workingWifiP2pGroupClient( boolean emulateInterfaceStatusChanged)2041     private void workingWifiP2pGroupClient(
2042             boolean emulateInterfaceStatusChanged) throws Exception {
2043         if (emulateInterfaceStatusChanged) {
2044             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
2045         }
2046         sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
2047 
2048         verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
2049         verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
2050         verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
2051         verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
2052         verify(mNetd, never()).tetherStartWithConfiguration(any());
2053 
2054         // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
2055         // is being removed.
2056         sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME);
2057         mTethering.interfaceRemoved(TEST_P2P_IFNAME);
2058 
2059         verify(mNetd, never()).tetherApplyDnsInterfaces();
2060         verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME);
2061         verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
2062         verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
2063         verify(mNetd, never()).tetherStop();
2064         verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME);
2065         verifyNoMoreInteractions(mNetd);
2066         // Asking for the last error after the per-interface state machine
2067         // has been reaped yields an unknown interface error.
2068         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
2069     }
2070 
2071     @Test
workingWifiP2pGroupOwnerWithIfaceChanged()2072     public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception {
2073         workingWifiP2pGroupOwner(true);
2074     }
2075 
2076     @Test
workingWifiP2pGroupOwnerSansIfaceChanged()2077     public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception {
2078         workingWifiP2pGroupOwner(false);
2079     }
2080 
workingWifiP2pGroupOwnerLegacyMode( boolean emulateInterfaceStatusChanged)2081     private void workingWifiP2pGroupOwnerLegacyMode(
2082             boolean emulateInterfaceStatusChanged) throws Exception {
2083         // change to legacy mode and update tethering information by chaning SIM
2084         when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
2085                 .thenReturn(new String[]{});
2086         final int fakeSubId = 1234;
2087         mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
2088 
2089         if (emulateInterfaceStatusChanged) {
2090             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
2091         }
2092         sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
2093 
2094         verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
2095         verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
2096         verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
2097         verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
2098         verify(mNetd, never()).tetherStartWithConfiguration(any());
2099         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
2100     }
2101     @Test
workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged()2102     public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception {
2103         workingWifiP2pGroupOwnerLegacyMode(true);
2104     }
2105 
2106     @Test
workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged()2107     public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception {
2108         workingWifiP2pGroupOwnerLegacyMode(false);
2109     }
2110 
2111     @Test
workingWifiP2pGroupClientWithIfaceChanged()2112     public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception {
2113         workingWifiP2pGroupClient(true);
2114     }
2115 
2116     @Test
workingWifiP2pGroupClientSansIfaceChanged()2117     public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception {
2118         workingWifiP2pGroupClient(false);
2119     }
2120 
setDataSaverEnabled(boolean enabled)2121     private void setDataSaverEnabled(boolean enabled) {
2122         final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED
2123                 : RESTRICT_BACKGROUND_STATUS_DISABLED;
2124         doReturn(status).when(mCm).getRestrictBackgroundStatus();
2125 
2126         final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED);
2127         mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL);
2128         mLooper.dispatchAll();
2129     }
2130 
2131     @Test
testDataSaverChanged()2132     public void testDataSaverChanged() {
2133         // Start Tethering.
2134         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
2135         runUsbTethering(upstreamState);
2136         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
2137         // Data saver is ON.
2138         setDataSaverEnabled(true);
2139         // Verify that tethering should be disabled.
2140         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2141         sendUsbBroadcast(true, true, -1 /* function */);
2142         mLooper.dispatchAll();
2143         assertEquals(mTethering.getTetheredIfaces(), new String[0]);
2144         reset(mUsbManager, mIPv6TetheringCoordinator);
2145 
2146         runUsbTethering(upstreamState);
2147         // Verify that user can start tethering again without turning OFF data saver.
2148         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
2149 
2150         // If data saver is keep ON with change event, tethering should not be OFF this time.
2151         setDataSaverEnabled(true);
2152         verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2153         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
2154 
2155         // If data saver is turned OFF, it should not change tethering.
2156         setDataSaverEnabled(false);
2157         verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2158         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
2159     }
2160 
assertContains(Collection<T> collection, T element)2161     private static <T> void assertContains(Collection<T> collection, T element) {
2162         assertTrue(element + " not found in " + collection, collection.contains(element));
2163     }
2164 
2165     private class ResultListener extends IIntResultListener.Stub {
2166         private final int mExpectedResult;
2167         private boolean mHasResult = false;
ResultListener(final int expectedResult)2168         ResultListener(final int expectedResult) {
2169             mExpectedResult = expectedResult;
2170         }
2171 
2172         @Override
onResult(final int resultCode)2173         public void onResult(final int resultCode) {
2174             mHasResult = true;
2175             if (resultCode != mExpectedResult) {
2176                 fail("expected result: " + mExpectedResult + " but actual result: " + resultCode);
2177             }
2178         }
2179 
assertHasResult()2180         public void assertHasResult() {
2181             if (!mHasResult) fail("No callback result");
2182         }
2183     }
2184 
2185     @Test
testMultipleStartTethering()2186     public void testMultipleStartTethering() throws Exception {
2187         final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
2188         final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
2189         final String serverAddr = "192.168.20.1";
2190         final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
2191         final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
2192         final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
2193 
2194         // Enable USB tethering and check that Tethering starts USB.
2195         mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), firstResult);
2196         mLooper.dispatchAll();
2197         firstResult.assertHasResult();
2198         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
2199         verifyNoMoreInteractions(mUsbManager);
2200 
2201         // Enable USB tethering again with the same request and expect no change to USB.
2202         mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), secondResult);
2203         mLooper.dispatchAll();
2204         secondResult.assertHasResult();
2205         verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2206         reset(mUsbManager);
2207 
2208         // Enable USB tethering with a different request and expect that USB is stopped and
2209         // started.
2210         mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
2211                   serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL), thirdResult);
2212         mLooper.dispatchAll();
2213         thirdResult.assertHasResult();
2214         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2215         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
2216 
2217         // Expect that when USB comes up, the DHCP server is configured with the requested address.
2218         mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true);
2219         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
2220         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
2221                 any(), any());
2222         verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
2223     }
2224 
2225     @Test
testRequestStaticIp()2226     public void testRequestStaticIp() throws Exception {
2227         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
2228                 TetheringConfiguration.TETHER_USB_NCM_FUNCTION);
2229         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
2230                 .thenReturn(new String[] {TEST_NCM_REGEX});
2231         sendConfigurationChanged();
2232 
2233         final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
2234         final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
2235         final String serverAddr = "192.168.0.123";
2236         final int clientAddrParceled = 0xc0a8002a;
2237         final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
2238                 ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
2239         mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
2240                   serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL), null);
2241         mLooper.dispatchAll();
2242         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
2243         mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
2244         sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION);
2245         verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
2246         verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
2247                 any());
2248         final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
2249         assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
2250         assertEquals(24, params.serverAddrPrefixLength);
2251         assertEquals(clientAddrParceled, params.singleClientAddr);
2252     }
2253 
2254     @Test
testUpstreamNetworkChanged()2255     public void testUpstreamNetworkChanged() {
2256         final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
2257                 mTetheringDependencies.mUpstreamNetworkMonitorSM;
2258         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
2259         initTetheringUpstream(upstreamState);
2260         stateMachine.chooseUpstreamType(true);
2261 
2262         verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
2263         verify(mNotificationUpdater, times(1)).onUpstreamCapabilitiesChanged(any());
2264     }
2265 
2266     @Test
testUpstreamCapabilitiesChanged()2267     public void testUpstreamCapabilitiesChanged() {
2268         final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM)
2269                 mTetheringDependencies.mUpstreamNetworkMonitorSM;
2270         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
2271         initTetheringUpstream(upstreamState);
2272         stateMachine.chooseUpstreamType(true);
2273 
2274         stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
2275         // Should have two onUpstreamCapabilitiesChanged().
2276         // One is called by reportUpstreamChanged(). One is called by EVENT_ON_CAPABILITIES.
2277         verify(mNotificationUpdater, times(2)).onUpstreamCapabilitiesChanged(any());
2278         reset(mNotificationUpdater);
2279 
2280         // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network
2281         // capabilities changed.
2282         final UpstreamNetworkState upstreamState2 = new UpstreamNetworkState(
2283                 upstreamState.linkProperties, upstreamState.networkCapabilities,
2284                 new Network(WIFI_NETID));
2285         stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState2);
2286         verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any());
2287     }
2288 
2289     @Test
testDumpTetheringLog()2290     public void testDumpTetheringLog() throws Exception {
2291         final FileDescriptor mockFd = mock(FileDescriptor.class);
2292         final PrintWriter mockPw = mock(PrintWriter.class);
2293         runUsbTethering(null);
2294         mLooper.startAutoDispatch();
2295         mTethering.dump(mockFd, mockPw, new String[0]);
2296         verify(mConfig).dump(any());
2297         verify(mEntitleMgr).dump(any());
2298         verify(mOffloadCtrl).dump(any());
2299         mLooper.stopAutoDispatch();
2300     }
2301 
2302     @Test
testExemptFromEntitlementCheck()2303     public void testExemptFromEntitlementCheck() throws Exception {
2304         setupForRequiredProvisioning();
2305         final TetheringRequestParcel wifiNotExemptRequest =
2306                 createTetheringRequestParcel(TETHERING_WIFI, null, null, false,
2307                         CONNECTIVITY_SCOPE_GLOBAL);
2308         mTethering.startTethering(wifiNotExemptRequest, null);
2309         mLooper.dispatchAll();
2310         verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
2311         verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
2312         assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
2313         mTethering.stopTethering(TETHERING_WIFI);
2314         mLooper.dispatchAll();
2315         verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
2316         reset(mEntitleMgr);
2317 
2318         setupForRequiredProvisioning();
2319         final TetheringRequestParcel wifiExemptRequest =
2320                 createTetheringRequestParcel(TETHERING_WIFI, null, null, true,
2321                         CONNECTIVITY_SCOPE_GLOBAL);
2322         mTethering.startTethering(wifiExemptRequest, null);
2323         mLooper.dispatchAll();
2324         verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
2325         verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
2326         assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
2327         mTethering.stopTethering(TETHERING_WIFI);
2328         mLooper.dispatchAll();
2329         verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
2330         reset(mEntitleMgr);
2331 
2332         // If one app enables tethering without provisioning check first, then another app enables
2333         // tethering of the same type but does not disable the provisioning check.
2334         setupForRequiredProvisioning();
2335         mTethering.startTethering(wifiExemptRequest, null);
2336         mLooper.dispatchAll();
2337         verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
2338         verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
2339         assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
2340         reset(mEntitleMgr);
2341         setupForRequiredProvisioning();
2342         mTethering.startTethering(wifiNotExemptRequest, null);
2343         mLooper.dispatchAll();
2344         verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
2345         verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
2346         assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
2347         mTethering.stopTethering(TETHERING_WIFI);
2348         mLooper.dispatchAll();
2349         verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
2350         reset(mEntitleMgr);
2351     }
2352 
setupForRequiredProvisioning()2353     private void setupForRequiredProvisioning() {
2354         // Produce some acceptable looking provision app setting if requested.
2355         when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
2356                 .thenReturn(PROVISIONING_APP_NAME);
2357         when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
2358                 .thenReturn(PROVISIONING_NO_UI_APP_NAME);
2359         // Act like the CarrierConfigManager is present and ready unless told otherwise.
2360         when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
2361                 .thenReturn(mCarrierConfigManager);
2362         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
2363         mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
2364         mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
2365         sendConfigurationChanged();
2366     }
2367 
buildV4UpstreamState(final LinkAddress address, final Network network, final String iface, final int transportType)2368     private static UpstreamNetworkState buildV4UpstreamState(final LinkAddress address,
2369             final Network network, final String iface, final int transportType) {
2370         final LinkProperties prop = new LinkProperties();
2371         prop.setInterfaceName(iface);
2372 
2373         prop.addLinkAddress(address);
2374 
2375         final NetworkCapabilities capabilities = new NetworkCapabilities()
2376                 .addTransportType(transportType);
2377         return new UpstreamNetworkState(prop, capabilities, network);
2378     }
2379 
updateV4Upstream(final LinkAddress ipv4Address, final Network network, final String iface, final int transportType)2380     private void updateV4Upstream(final LinkAddress ipv4Address, final Network network,
2381             final String iface, final int transportType) {
2382         final UpstreamNetworkState upstream = buildV4UpstreamState(ipv4Address, network, iface,
2383                 transportType);
2384         mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage(
2385                 Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK,
2386                 UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
2387                 0,
2388                 upstream);
2389         mLooper.dispatchAll();
2390     }
2391 
2392     @Test
testHandleIpConflict()2393     public void testHandleIpConflict() throws Exception {
2394         final Network wifiNetwork = new Network(200);
2395         final Network[] allNetworks = { wifiNetwork };
2396         doReturn(allNetworks).when(mCm).getAllNetworks();
2397         runUsbTethering(null);
2398         final ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor =
2399                 ArgumentCaptor.forClass(InterfaceConfigurationParcel.class);
2400         verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture());
2401         final String ipv4Address = ifaceConfigCaptor.getValue().ipv4Addr;
2402         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
2403                 any(), any());
2404         reset(mUsbManager);
2405 
2406         // Cause a prefix conflict by assigning a /30 out of the downstream's /24 to the upstream.
2407         updateV4Upstream(new LinkAddress(InetAddresses.parseNumericAddress(ipv4Address), 30),
2408                 wifiNetwork, TEST_WIFI_IFNAME, TRANSPORT_WIFI);
2409         // verify turn off usb tethering
2410         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2411         sendUsbBroadcast(true, true, -1 /* function */);
2412         mLooper.dispatchAll();
2413         // verify restart usb tethering
2414         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
2415     }
2416 
2417     @Test
testNoAddressAvailable()2418     public void testNoAddressAvailable() throws Exception {
2419         final Network wifiNetwork = new Network(200);
2420         final Network btNetwork = new Network(201);
2421         final Network mobileNetwork = new Network(202);
2422         final Network[] allNetworks = { wifiNetwork, btNetwork, mobileNetwork };
2423         doReturn(allNetworks).when(mCm).getAllNetworks();
2424         runUsbTethering(null);
2425         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
2426                 any(), any());
2427         reset(mUsbManager);
2428         final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
2429         when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
2430         final ArgumentCaptor<TetheredInterfaceCallback> callbackCaptor =
2431                 ArgumentCaptor.forClass(TetheredInterfaceCallback.class);
2432         mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null);
2433         mLooper.dispatchAll();
2434         verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
2435         TetheredInterfaceCallback ethCallback = callbackCaptor.getValue();
2436         ethCallback.onAvailable(TEST_ETH_IFNAME);
2437         mLooper.dispatchAll();
2438         reset(mUsbManager, mEm);
2439 
2440         updateV4Upstream(new LinkAddress("192.168.0.100/16"), wifiNetwork, TEST_WIFI_IFNAME,
2441                 TRANSPORT_WIFI);
2442         updateV4Upstream(new LinkAddress("172.16.0.0/12"), btNetwork, TEST_BT_IFNAME,
2443                 TRANSPORT_BLUETOOTH);
2444         updateV4Upstream(new LinkAddress("10.0.0.0/8"), mobileNetwork, TEST_MOBILE_IFNAME,
2445                 TRANSPORT_CELLULAR);
2446 
2447         mLooper.dispatchAll();
2448         // verify turn off usb tethering
2449         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2450         // verify turn off ethernet tethering
2451         verify(mockRequest).release();
2452         sendUsbBroadcast(true, true, -1 /* function */);
2453         ethCallback.onUnavailable();
2454         mLooper.dispatchAll();
2455         // verify restart usb tethering
2456         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
2457         // verify restart ethernet tethering
2458         verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
2459         ethCallback = callbackCaptor.getValue();
2460         ethCallback.onAvailable(TEST_ETH_IFNAME);
2461 
2462         reset(mUsbManager, mEm);
2463         when(mNetd.interfaceGetList())
2464                 .thenReturn(new String[] {
2465                         TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_RNDIS_IFNAME, TEST_P2P_IFNAME,
2466                         TEST_NCM_IFNAME, TEST_ETH_IFNAME});
2467 
2468         mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true);
2469         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
2470         assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_RNDIS_IFNAME);
2471         assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_ETH_IFNAME);
2472         assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest(
2473                 TEST_RNDIS_IFNAME));
2474         assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest(TEST_ETH_IFNAME));
2475     }
2476 
2477     @Test
testProvisioningNeededButUnavailable()2478     public void testProvisioningNeededButUnavailable() throws Exception {
2479         assertTrue(mTethering.isTetheringSupported());
2480         verify(mPackageManager, never()).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
2481 
2482         setupForRequiredProvisioning();
2483         assertTrue(mTethering.isTetheringSupported());
2484         verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
2485         reset(mPackageManager);
2486 
2487         doThrow(PackageManager.NameNotFoundException.class).when(mPackageManager).getPackageInfo(
2488                 PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
2489         setupForRequiredProvisioning();
2490         assertFalse(mTethering.isTetheringSupported());
2491         verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
2492     }
2493 
2494     @Test
testUpdateConnectedClients()2495     public void testUpdateConnectedClients() throws Exception {
2496         TestTetheringEventCallback callback = new TestTetheringEventCallback();
2497         runAsShell(NETWORK_SETTINGS, () -> {
2498             mTethering.registerTetheringEventCallback(callback);
2499             mLooper.dispatchAll();
2500         });
2501         callback.expectTetheredClientChanged(Collections.emptyList());
2502 
2503         IDhcpEventCallbacks eventCallbacks;
2504         final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor =
2505                  ArgumentCaptor.forClass(IDhcpEventCallbacks.class);
2506         // Run local only tethering.
2507         mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
2508         sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
2509         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
2510                 any(), dhcpEventCbsCaptor.capture());
2511         eventCallbacks = dhcpEventCbsCaptor.getValue();
2512         // Update lease for local only tethering.
2513         final MacAddress testMac1 = MacAddress.fromString("11:11:11:11:11:11");
2514         final ArrayList<DhcpLeaseParcelable> p2pLeases = new ArrayList<>();
2515         p2pLeases.add(createDhcpLeaseParcelable("clientId1", testMac1, "192.168.50.24", 24,
2516                 Long.MAX_VALUE, "test1"));
2517         notifyDhcpLeasesChanged(p2pLeases, eventCallbacks);
2518         final List<TetheredClient> clients = toTetheredClients(p2pLeases, TETHERING_WIFI_P2P);
2519         callback.expectTetheredClientChanged(clients);
2520         reset(mDhcpServer);
2521 
2522         // Run wifi tethering.
2523         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
2524         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
2525         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
2526                 any(), dhcpEventCbsCaptor.capture());
2527         eventCallbacks = dhcpEventCbsCaptor.getValue();
2528         // Update mac address from softAp callback before getting dhcp lease.
2529         final ArrayList<WifiClient> wifiClients = new ArrayList<>();
2530         final MacAddress testMac2 = MacAddress.fromString("22:22:22:22:22:22");
2531         final WifiClient testClient = mock(WifiClient.class);
2532         when(testClient.getMacAddress()).thenReturn(testMac2);
2533         wifiClients.add(testClient);
2534         mSoftApCallback.onConnectedClientsChanged(wifiClients);
2535         final TetheredClient noAddrClient = new TetheredClient(testMac2,
2536                 Collections.emptyList() /* addresses */, TETHERING_WIFI);
2537         clients.add(noAddrClient);
2538         callback.expectTetheredClientChanged(clients);
2539 
2540         // Update dhcp lease for wifi tethering.
2541         clients.remove(noAddrClient);
2542         final ArrayList<DhcpLeaseParcelable> wifiLeases = new ArrayList<>();
2543         wifiLeases.add(createDhcpLeaseParcelable("clientId2", testMac2, "192.168.43.24", 24,
2544                 Long.MAX_VALUE, "test2"));
2545         notifyDhcpLeasesChanged(wifiLeases, eventCallbacks);
2546         clients.addAll(toTetheredClients(wifiLeases, TETHERING_WIFI));
2547         callback.expectTetheredClientChanged(clients);
2548 
2549         // Test onStarted callback that register second callback when tethering is running.
2550         TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
2551         runAsShell(NETWORK_SETTINGS, () -> {
2552             mTethering.registerTetheringEventCallback(callback2);
2553             mLooper.dispatchAll();
2554         });
2555         callback2.expectTetheredClientChanged(clients);
2556     }
2557 
notifyDhcpLeasesChanged(List<DhcpLeaseParcelable> leaseParcelables, IDhcpEventCallbacks callback)2558     private void notifyDhcpLeasesChanged(List<DhcpLeaseParcelable> leaseParcelables,
2559             IDhcpEventCallbacks callback) throws Exception {
2560         callback.onLeasesChanged(leaseParcelables);
2561         mLooper.dispatchAll();
2562     }
2563 
toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables, int type)2564     private List<TetheredClient> toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables,
2565             int type) throws Exception {
2566         final ArrayList<TetheredClient> leases = new ArrayList<>();
2567         for (DhcpLeaseParcelable lease : leaseParcelables) {
2568             final LinkAddress address = new LinkAddress(
2569                     intToInet4AddressHTH(lease.netAddr), lease.prefixLength,
2570                     0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */,
2571                     lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */);
2572 
2573             final MacAddress macAddress = MacAddress.fromBytes(lease.hwAddr);
2574 
2575             final AddressInfo addressInfo = new TetheredClient.AddressInfo(address, lease.hostname);
2576             leases.add(new TetheredClient(
2577                     macAddress,
2578                     Collections.singletonList(addressInfo),
2579                     type));
2580         }
2581 
2582         return leases;
2583     }
2584 
createDhcpLeaseParcelable(final String clientId, final MacAddress hwAddr, final String netAddr, final int prefixLength, final long expTime, final String hostname)2585     private DhcpLeaseParcelable createDhcpLeaseParcelable(final String clientId,
2586             final MacAddress hwAddr, final String netAddr, final int prefixLength,
2587             final long expTime, final String hostname) throws Exception {
2588         final DhcpLeaseParcelable lease = new DhcpLeaseParcelable();
2589         lease.clientId = clientId.getBytes();
2590         lease.hwAddr = hwAddr.toByteArray();
2591         lease.netAddr = inet4AddressToIntHTH(
2592                 (Inet4Address) InetAddresses.parseNumericAddress(netAddr));
2593         lease.prefixLength = prefixLength;
2594         lease.expTime = expTime;
2595         lease.hostname = hostname;
2596 
2597         return lease;
2598     }
2599 
2600     @Test
testBluetoothTethering()2601     public void testBluetoothTethering() throws Exception {
2602         // Switch to @IgnoreUpTo(Build.VERSION_CODES.S_V2) when it is available for AOSP.
2603         assumeTrue(isAtLeastT());
2604 
2605         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
2606         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
2607         mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
2608         mLooper.dispatchAll();
2609         verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
2610         result.assertHasResult();
2611 
2612         mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
2613         mLooper.dispatchAll();
2614         verifyNetdCommandForBtSetup();
2615 
2616         // If PAN disconnect, tethering should also be stopped.
2617         mTetheredInterfaceCallbackShim.onUnavailable();
2618         mLooper.dispatchAll();
2619         verifyNetdCommandForBtTearDown();
2620 
2621         // Tethering could restart if PAN reconnect.
2622         mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
2623         mLooper.dispatchAll();
2624         verifyNetdCommandForBtSetup();
2625 
2626         // Pretend that bluetooth tethering was disabled.
2627         mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */);
2628         mTethering.stopTethering(TETHERING_BLUETOOTH);
2629         mLooper.dispatchAll();
2630         verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */);
2631 
2632         verifyNetdCommandForBtTearDown();
2633     }
2634 
2635     @Test
testBluetoothTetheringBeforeT()2636     public void testBluetoothTetheringBeforeT() throws Exception {
2637         // Switch to @IgnoreAfter(Build.VERSION_CODES.S_V2) when it is available for AOSP.
2638         assumeFalse(isAtLeastT());
2639 
2640         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
2641         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
2642         mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
2643         mLooper.dispatchAll();
2644         verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
2645         result.assertHasResult();
2646 
2647         mTethering.interfaceAdded(TEST_BT_IFNAME);
2648         mLooper.dispatchAll();
2649 
2650         mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
2651         mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
2652         final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
2653         mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
2654         mLooper.dispatchAll();
2655         tetherResult.assertHasResult();
2656 
2657         verifyNetdCommandForBtSetup();
2658 
2659         // Turning tethering on a second time does not bind to the PAN service again, since it's
2660         // already bound.
2661         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
2662         final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
2663         mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), secondResult);
2664         mLooper.dispatchAll();
2665         verifySetBluetoothTethering(true /* enable */, false /* bindToPanService */);
2666         secondResult.assertHasResult();
2667 
2668         mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */);
2669         mTethering.stopTethering(TETHERING_BLUETOOTH);
2670         mLooper.dispatchAll();
2671         final ResultListener untetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
2672         mTethering.untether(TEST_BT_IFNAME, untetherResult);
2673         mLooper.dispatchAll();
2674         untetherResult.assertHasResult();
2675         verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */);
2676 
2677         verifyNetdCommandForBtTearDown();
2678     }
2679 
2680     @Test
testBluetoothServiceDisconnects()2681     public void testBluetoothServiceDisconnects() throws Exception {
2682         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
2683         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
2684         mTethering.startTethering(createTetheringRequestParcel(TETHERING_BLUETOOTH), result);
2685         mLooper.dispatchAll();
2686         ServiceListener panListener = verifySetBluetoothTethering(true /* enable */,
2687                 true /* bindToPanService */);
2688         result.assertHasResult();
2689 
2690         mTethering.interfaceAdded(TEST_BT_IFNAME);
2691         mLooper.dispatchAll();
2692 
2693         if (isAtLeastT()) {
2694             mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
2695             mLooper.dispatchAll();
2696         } else {
2697             mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
2698             mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
2699             final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
2700             mTethering.tether(TEST_BT_IFNAME, IpServer.STATE_TETHERED, tetherResult);
2701             mLooper.dispatchAll();
2702             tetherResult.assertHasResult();
2703         }
2704 
2705         verifyNetdCommandForBtSetup();
2706 
2707         panListener.onServiceDisconnected(BluetoothProfile.PAN);
2708         mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
2709         mLooper.dispatchAll();
2710 
2711         verifyNetdCommandForBtTearDown();
2712     }
2713 
mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn)2714     private void mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn) {
2715         when(mBluetoothAdapter.isEnabled()).thenReturn(bluetoothOn);
2716         when(mBluetoothPan.isTetheringOn()).thenReturn(tetheringOn);
2717     }
2718 
verifyNetdCommandForBtSetup()2719     private void verifyNetdCommandForBtSetup() throws Exception {
2720         if (isAtLeastT()) {
2721             verify(mNetd).interfaceSetCfg(argThat(cfg -> TEST_BT_IFNAME.equals(cfg.ifName)
2722                     && assertContainsFlag(cfg.flags, INetd.IF_STATE_UP)));
2723         }
2724         verify(mNetd).tetherInterfaceAdd(TEST_BT_IFNAME);
2725         verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME);
2726         verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME),
2727                 anyString(), anyString());
2728         verify(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
2729         verify(mNetd).tetherStartWithConfiguration(any());
2730         verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME),
2731                 anyString(), anyString());
2732         verifyNoMoreInteractions(mNetd);
2733         reset(mNetd);
2734     }
2735 
assertContainsFlag(String[] flags, String match)2736     private boolean assertContainsFlag(String[] flags, String match) {
2737         for (String flag : flags) {
2738             if (flag.equals(match)) return true;
2739         }
2740         return false;
2741     }
2742 
verifyNetdCommandForBtTearDown()2743     private void verifyNetdCommandForBtTearDown() throws Exception {
2744         verify(mNetd).tetherApplyDnsInterfaces();
2745         verify(mNetd).tetherInterfaceRemove(TEST_BT_IFNAME);
2746         verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME);
2747         // One is ipv4 address clear (set to 0.0.0.0), another is set interface down which only
2748         // happen after T. Before T, the interface configuration control in bluetooth side.
2749         verify(mNetd, times(isAtLeastT() ? 2 : 1)).interfaceSetCfg(
2750                 any(InterfaceConfigurationParcel.class));
2751         verify(mNetd).tetherStop();
2752         verify(mNetd).ipfwdDisableForwarding(TETHERING_NAME);
2753         reset(mNetd);
2754     }
2755 
2756     // If bindToPanService is true, this function would return ServiceListener which could notify
2757     // PanService is connected or disconnected.
verifySetBluetoothTethering(final boolean enable, final boolean bindToPanService)2758     private ServiceListener verifySetBluetoothTethering(final boolean enable,
2759             final boolean bindToPanService) throws Exception {
2760         ServiceListener listener = null;
2761         verify(mBluetoothAdapter).isEnabled();
2762         if (bindToPanService) {
2763             final ArgumentCaptor<ServiceListener> listenerCaptor =
2764                     ArgumentCaptor.forClass(ServiceListener.class);
2765             verify(mBluetoothAdapter).getProfileProxy(eq(mServiceContext), listenerCaptor.capture(),
2766                     eq(BluetoothProfile.PAN));
2767             listener = listenerCaptor.getValue();
2768             listener.onServiceConnected(BluetoothProfile.PAN, mBluetoothPan);
2769             mLooper.dispatchAll();
2770         } else {
2771             verify(mBluetoothAdapter, never()).getProfileProxy(eq(mServiceContext), any(),
2772                     anyInt());
2773         }
2774 
2775         if (isAtLeastT()) {
2776             if (enable) {
2777                 final ArgumentCaptor<TetheredInterfaceCallbackShim> callbackCaptor =
2778                         ArgumentCaptor.forClass(TetheredInterfaceCallbackShim.class);
2779                 verify(mBluetoothPanShim).requestTetheredInterface(any(), callbackCaptor.capture());
2780                 mTetheredInterfaceCallbackShim = callbackCaptor.getValue();
2781             } else {
2782                 verify(mTetheredInterfaceRequestShim).release();
2783             }
2784         } else {
2785             verify(mBluetoothPan).setBluetoothTethering(enable);
2786         }
2787         verify(mBluetoothPan).isTetheringOn();
2788         verifyNoMoreInteractions(mBluetoothAdapter, mBluetoothPan);
2789         reset(mBluetoothAdapter, mBluetoothPan);
2790 
2791         return listener;
2792     }
2793 
runDualStackUsbTethering(final String expectedIface)2794     private void runDualStackUsbTethering(final String expectedIface) throws Exception {
2795         when(mNetd.interfaceGetList()).thenReturn(new String[] {expectedIface});
2796         when(mRouterAdvertisementDaemon.start())
2797                 .thenReturn(true);
2798         final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
2799         runUsbTethering(upstreamState);
2800 
2801         verify(mNetd).interfaceGetList();
2802         verify(mNetd).tetherAddForward(expectedIface, TEST_MOBILE_IFNAME);
2803         verify(mNetd).ipfwdAddInterfaceForward(expectedIface, TEST_MOBILE_IFNAME);
2804 
2805         verify(mRouterAdvertisementDaemon).start();
2806         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
2807                 any(), any());
2808         sendIPv6TetherUpdates(upstreamState);
2809         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
2810         verify(mRouterAdvertisementDaemon).buildNewRa(any(), notNull());
2811         verify(mNetd).tetherApplyDnsInterfaces();
2812     }
2813 
forceUsbTetheringUse(final int function)2814     private void forceUsbTetheringUse(final int function) {
2815         Settings.Global.putInt(mContentResolver, TETHER_FORCE_USB_FUNCTIONS, function);
2816         final ContentObserver observer = mTethering.getSettingsObserverForTest();
2817         observer.onChange(false /* selfChange */);
2818         mLooper.dispatchAll();
2819     }
2820 
verifyUsbTetheringStopDueToSettingChange(final String iface)2821     private void verifyUsbTetheringStopDueToSettingChange(final String iface) {
2822         verify(mUsbManager, times(2)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2823         mTethering.interfaceRemoved(iface);
2824         sendUsbBroadcast(true, true, -1 /* no functions enabled */);
2825         reset(mUsbManager, mNetd, mDhcpServer, mRouterAdvertisementDaemon,
2826                 mIPv6TetheringCoordinator, mDadProxy);
2827     }
2828 
2829     @Test
testUsbFunctionConfigurationChange()2830     public void testUsbFunctionConfigurationChange() throws Exception {
2831         // Run TETHERING_NCM.
2832         runNcmTethering();
2833         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
2834                 any(), any());
2835 
2836         // Change the USB tethering function to NCM. Because the USB tethering function was set to
2837         // RNDIS (the default), tethering is stopped.
2838         forceUsbTetheringUse(TETHER_USB_NCM_FUNCTION);
2839         verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME);
2840 
2841         // If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be
2842         // available.
2843         final ResultListener ncmResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL);
2844         mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), ncmResult);
2845         mLooper.dispatchAll();
2846         ncmResult.assertHasResult();
2847 
2848         // Run TETHERING_USB with ncm configuration.
2849         runDualStackUsbTethering(TEST_NCM_IFNAME);
2850 
2851         // Change configuration to rndis.
2852         forceUsbTetheringUse(TETHER_USB_RNDIS_FUNCTION);
2853         verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME);
2854 
2855         // Run TETHERING_USB with rndis configuration.
2856         runDualStackUsbTethering(TEST_RNDIS_IFNAME);
2857         runStopUSBTethering();
2858     }
2859 
getAllSupportedTetheringTypes()2860     public static ArraySet<Integer> getAllSupportedTetheringTypes() {
2861         return new ArraySet<>(new Integer[] { TETHERING_USB, TETHERING_NCM, TETHERING_WIFI,
2862                 TETHERING_WIFI_P2P, TETHERING_BLUETOOTH, TETHERING_ETHERNET });
2863     }
2864 
2865     @Test
testTetheringSupported()2866     public void testTetheringSupported() throws Exception {
2867         final ArraySet<Integer> expectedTypes = getAllSupportedTetheringTypes();
2868         // Check tethering is supported after initialization.
2869         setTetheringSupported(true /* supported */);
2870         TestTetheringEventCallback callback = new TestTetheringEventCallback();
2871         mTethering.registerTetheringEventCallback(callback);
2872         mLooper.dispatchAll();
2873         updateConfigAndVerifySupported(callback, expectedTypes);
2874 
2875         // Could disable tethering supported by settings.
2876         Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED, 0);
2877         updateConfigAndVerifySupported(callback, new ArraySet<>());
2878 
2879         // Could disable tethering supported by user restriction.
2880         setTetheringSupported(true /* supported */);
2881         updateConfigAndVerifySupported(callback, expectedTypes);
2882         when(mUserManager.hasUserRestriction(
2883                 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(true);
2884         updateConfigAndVerifySupported(callback, new ArraySet<>());
2885 
2886         // Tethering is supported if it has any supported downstream.
2887         setTetheringSupported(true /* supported */);
2888         updateConfigAndVerifySupported(callback, expectedTypes);
2889         // Usb tethering is not supported:
2890         expectedTypes.remove(TETHERING_USB);
2891         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
2892                 .thenReturn(new String[0]);
2893         updateConfigAndVerifySupported(callback, expectedTypes);
2894         // Wifi tethering is not supported:
2895         expectedTypes.remove(TETHERING_WIFI);
2896         when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
2897                 .thenReturn(new String[0]);
2898         updateConfigAndVerifySupported(callback, expectedTypes);
2899         // Bluetooth tethering is not supported:
2900         expectedTypes.remove(TETHERING_BLUETOOTH);
2901         when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
2902                 .thenReturn(new String[0]);
2903 
2904         if (isAtLeastT()) {
2905             updateConfigAndVerifySupported(callback, expectedTypes);
2906 
2907             // P2p tethering is not supported:
2908             expectedTypes.remove(TETHERING_WIFI_P2P);
2909             when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
2910                     .thenReturn(new String[0]);
2911             updateConfigAndVerifySupported(callback, expectedTypes);
2912             // Ncm tethering is not supported:
2913             expectedTypes.remove(TETHERING_NCM);
2914             when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
2915                     .thenReturn(new String[0]);
2916             updateConfigAndVerifySupported(callback, expectedTypes);
2917             // Ethernet tethering (last supported type) is not supported:
2918             expectedTypes.remove(TETHERING_ETHERNET);
2919             mForceEthernetServiceUnavailable = true;
2920             updateConfigAndVerifySupported(callback, new ArraySet<>());
2921 
2922         } else {
2923             // If wifi, usb and bluetooth are all not supported, all the types are not supported.
2924             expectedTypes.clear();
2925             updateConfigAndVerifySupported(callback, expectedTypes);
2926         }
2927     }
2928 
updateConfigAndVerifySupported(final TestTetheringEventCallback callback, final ArraySet<Integer> expectedTypes)2929     private void updateConfigAndVerifySupported(final TestTetheringEventCallback callback,
2930             final ArraySet<Integer> expectedTypes) {
2931         sendConfigurationChanged();
2932 
2933         assertEquals(expectedTypes.size() > 0, mTethering.isTetheringSupported());
2934         callback.expectSupportedTetheringTypes(expectedTypes);
2935     }
2936     // TODO: Test that a request for hotspot mode doesn't interfere with an
2937     // already operating tethering mode interface.
2938 }
2939