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