• 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.Manifest.permission.NETWORK_STACK;
21 import static android.content.pm.PackageManager.GET_ACTIVITIES;
22 import static android.content.pm.PackageManager.PERMISSION_DENIED;
23 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
24 import static android.hardware.usb.UsbManager.USB_CONFIGURED;
25 import static android.hardware.usb.UsbManager.USB_CONNECTED;
26 import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM;
27 import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
28 import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
29 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
30 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
31 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
32 import static android.net.ConnectivityManager.TYPE_WIFI;
33 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
34 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
35 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
36 import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
37 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
38 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
39 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
40 import static android.net.RouteInfo.RTN_UNICAST;
41 import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
42 import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
43 import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
44 import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
45 import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
46 import static android.net.TetheringManager.TETHERING_BLUETOOTH;
47 import static android.net.TetheringManager.TETHERING_ETHERNET;
48 import static android.net.TetheringManager.TETHERING_NCM;
49 import static android.net.TetheringManager.TETHERING_USB;
50 import static android.net.TetheringManager.TETHERING_VIRTUAL;
51 import static android.net.TetheringManager.TETHERING_WIFI;
52 import static android.net.TetheringManager.TETHERING_WIFI_P2P;
53 import static android.net.TetheringManager.TETHER_ERROR_DUPLICATE_REQUEST;
54 import static android.net.TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
55 import static android.net.TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
56 import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
57 import static android.net.TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
58 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
59 import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_REQUEST;
60 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
61 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
62 import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
63 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
64 import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
65 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
66 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
67 import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
68 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
69 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
70 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
71 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
72 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
73 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
74 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
75 
76 import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
77 import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
78 import static com.android.modules.utils.build.SdkLevel.isAtLeastV;
79 import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
80 import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
81 import static com.android.net.module.util.NetworkStackConstants.RFC7421_PREFIX_LENGTH;
82 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_HIDL_1_0;
83 import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
84 import static com.android.networkstack.tethering.TestConnectivityManager.BROADCAST_FIRST;
85 import static com.android.networkstack.tethering.TestConnectivityManager.CALLBACKS_FIRST;
86 import static com.android.networkstack.tethering.Tethering.UserRestrictionActionListener;
87 import static com.android.networkstack.tethering.TetheringConfiguration.TETHERING_LOCAL_NETWORK_AGENT;
88 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS;
89 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_NCM_FUNCTION;
90 import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION;
91 import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE;
92 import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES;
93 import static com.android.testutils.TestPermissionUtil.runAsShell;
94 
95 import static org.junit.Assert.assertArrayEquals;
96 import static org.junit.Assert.assertEquals;
97 import static org.junit.Assert.assertFalse;
98 import static org.junit.Assert.assertNotNull;
99 import static org.junit.Assert.assertNull;
100 import static org.junit.Assert.assertTrue;
101 import static org.junit.Assert.fail;
102 import static org.junit.Assume.assumeTrue;
103 import static org.mockito.ArgumentMatchers.argThat;
104 import static org.mockito.ArgumentMatchers.notNull;
105 import static org.mockito.ArgumentMatchers.anyInt;
106 import static org.mockito.ArgumentMatchers.anyString;
107 import static org.mockito.ArgumentMatchers.eq;
108 import static org.mockito.Mockito.any;
109 import static org.mockito.Mockito.atLeast;
110 import static org.mockito.Mockito.atLeastOnce;
111 import static org.mockito.Mockito.doReturn;
112 import static org.mockito.Mockito.doThrow;
113 import static org.mockito.Mockito.inOrder;
114 import static org.mockito.Mockito.mock;
115 import static org.mockito.Mockito.never;
116 import static org.mockito.Mockito.reset;
117 import static org.mockito.Mockito.spy;
118 import static org.mockito.Mockito.timeout;
119 import static org.mockito.Mockito.times;
120 import static org.mockito.Mockito.verify;
121 import static org.mockito.Mockito.verifyNoMoreInteractions;
122 import static org.mockito.Mockito.when;
123 
124 import android.app.usage.NetworkStatsManager;
125 import android.bluetooth.BluetoothAdapter;
126 import android.bluetooth.BluetoothPan;
127 import android.bluetooth.BluetoothProfile;
128 import android.bluetooth.BluetoothProfile.ServiceListener;
129 import android.content.BroadcastReceiver;
130 import android.content.ContentResolver;
131 import android.content.Context;
132 import android.content.Intent;
133 import android.content.IntentFilter;
134 import android.content.pm.ApplicationInfo;
135 import android.content.pm.PackageManager;
136 import android.content.res.Resources;
137 import android.database.ContentObserver;
138 import android.hardware.usb.UsbManager;
139 import android.net.ConnectivityManager;
140 import android.net.ConnectivityManager.NetworkCallback;
141 import android.net.EthernetManager;
142 import android.net.EthernetManager.TetheredInterfaceCallback;
143 import android.net.EthernetManager.TetheredInterfaceRequest;
144 import android.net.IConnectivityManager;
145 import android.net.IIntResultListener;
146 import android.net.INetd;
147 import android.net.ITetheringEventCallback;
148 import android.net.InetAddresses;
149 import android.net.InterfaceConfigurationParcel;
150 import android.net.IpPrefix;
151 import android.net.LinkAddress;
152 import android.net.LinkProperties;
153 import android.net.MacAddress;
154 import android.net.Network;
155 import android.net.NetworkCapabilities;
156 import android.net.NetworkRequest;
157 import android.net.RouteInfo;
158 import android.net.TetherStatesParcel;
159 import android.net.TetheredClient;
160 import android.net.TetheredClient.AddressInfo;
161 import android.net.TetheringCallbackStartedParcel;
162 import android.net.TetheringConfigurationParcel;
163 import android.net.TetheringInterface;
164 import android.net.TetheringManager;
165 import android.net.TetheringManager.TetheringRequest;
166 import android.net.dhcp.DhcpLeaseParcelable;
167 import android.net.dhcp.DhcpServerCallbacks;
168 import android.net.dhcp.DhcpServingParamsParcel;
169 import android.net.dhcp.IDhcpEventCallbacks;
170 import android.net.dhcp.IDhcpServer;
171 import android.net.ip.DadProxy;
172 import android.net.ip.IpServer;
173 import android.net.ip.RouterAdvertisementDaemon;
174 import android.net.wifi.SoftApConfiguration;
175 import android.net.wifi.SoftApState;
176 import android.net.wifi.WifiClient;
177 import android.net.wifi.WifiManager;
178 import android.net.wifi.WifiManager.SoftApCallback;
179 import android.net.wifi.WifiSsid;
180 import android.net.wifi.p2p.WifiP2pGroup;
181 import android.net.wifi.p2p.WifiP2pInfo;
182 import android.net.wifi.p2p.WifiP2pManager;
183 import android.os.Build;
184 import android.os.Bundle;
185 import android.os.Handler;
186 import android.os.Looper;
187 import android.os.PersistableBundle;
188 import android.os.RemoteException;
189 import android.os.UserHandle;
190 import android.os.UserManager;
191 import android.os.test.TestLooper;
192 import android.provider.Settings;
193 import android.telephony.CarrierConfigManager;
194 import android.telephony.PhoneStateListener;
195 import android.telephony.TelephonyManager;
196 import android.test.mock.MockContentResolver;
197 import android.util.ArrayMap;
198 import android.util.ArraySet;
199 
200 import androidx.annotation.NonNull;
201 import androidx.annotation.Nullable;
202 import androidx.test.filters.SmallTest;
203 import androidx.test.runner.AndroidJUnit4;
204 
205 import com.android.internal.util.test.BroadcastInterceptingContext;
206 import com.android.internal.util.test.FakeSettingsProvider;
207 import com.android.modules.utils.build.SdkLevel;
208 import com.android.net.module.util.CollectionUtils;
209 import com.android.net.module.util.InterfaceParams;
210 import com.android.net.module.util.PrivateAddressCoordinator;
211 import com.android.net.module.util.RoutingCoordinatorManager;
212 import com.android.net.module.util.RoutingCoordinatorService;
213 import com.android.net.module.util.SharedLog;
214 import com.android.net.module.util.ip.IpNeighborMonitor;
215 import com.android.networkstack.apishim.common.BluetoothPanShim;
216 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceCallbackShim;
217 import com.android.networkstack.apishim.common.BluetoothPanShim.TetheredInterfaceRequestShim;
218 import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
219 import com.android.networkstack.tethering.TestConnectivityManager.TestNetworkAgent;
220 import com.android.networkstack.tethering.metrics.TetheringMetrics;
221 import com.android.testutils.DevSdkIgnoreRule;
222 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
223 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
224 import com.android.testutils.MiscAsserts;
225 import com.android.testutils.com.android.testutils.SetFeatureFlagsRule;
226 
227 import org.junit.After;
228 import org.junit.Before;
229 import org.junit.BeforeClass;
230 import org.junit.Rule;
231 import org.junit.Test;
232 import org.junit.runner.RunWith;
233 import org.mockito.ArgumentCaptor;
234 import org.mockito.InOrder;
235 import org.mockito.Mock;
236 import org.mockito.MockitoAnnotations;
237 
238 import java.io.FileDescriptor;
239 import java.io.PrintWriter;
240 import java.net.Inet4Address;
241 import java.net.Inet6Address;
242 import java.nio.charset.StandardCharsets;
243 import java.util.ArrayList;
244 import java.util.Arrays;
245 import java.util.Collection;
246 import java.util.Collections;
247 import java.util.List;
248 import java.util.Set;
249 import java.util.Vector;
250 import java.util.concurrent.Executor;
251 
252 @RunWith(AndroidJUnit4.class)
253 @SmallTest
254 public class TetheringTest {
255     @Rule public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
256 
257     final ArrayMap<String, Boolean> mFeatureFlags = new ArrayMap<>();
258     // This will set feature flags from @FeatureFlag annotations
259     // into the map before setUp() runs.
260     @Rule
261     public final SetFeatureFlagsRule mSetFeatureFlagsRule =
262             new SetFeatureFlagsRule((name, enabled) -> {
263                 mFeatureFlags.put(name, enabled);
264                 return null;
265             }, (name) -> mFeatureFlags.getOrDefault(name, false));
266 
267     private static final int IFINDEX_OFFSET = 100;
268 
269     private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0";
270     private static final String TEST_DUN_IFNAME = "test_dun0";
271     private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0";
272     private static final String TEST_RNDIS_IFNAME = "test_rndis0";
273     private static final String TEST_WIFI_IFNAME = "test_wlan0";
274     private static final String TEST_WLAN_IFNAME = "test_wlan1";
275     private static final String TEST_WLAN2_IFNAME = "test_wlan2";
276     private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0";
277     private static final String TEST_NCM_IFNAME = "test_ncm0";
278     private static final String TEST_ETH_IFNAME = "test_eth0";
279     private static final String TEST_VIRT_IFNAME = "test_virt0";
280     private static final String TEST_BT_IFNAME = "test_pan0";
281     private static final String TETHERING_NAME = "Tethering";
282     private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
283     private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
284     private static final String TEST_RNDIS_REGEX = "test_rndis\\d";
285     private static final String TEST_NCM_REGEX = "test_ncm\\d";
286     private static final String TEST_WIFI_REGEX = "test_wlan\\d";
287     private static final String TEST_P2P_REGEX = "test_p2p-p2p\\d-.*";
288     private static final String TEST_BT_REGEX = "test_pan\\d";
289     private static final int TEST_CALLER_UID = 1000;
290     private static final int TEST_CALLER_UID_2 = 2000;
291     private static final String TEST_CALLER_PKG = "com.test.tethering";
292     private static final String TEST_CALLER_PKG_2 = "com.test.tethering2";
293     private static final int CELLULAR_NETID = 100;
294     private static final int WIFI_NETID = 101;
295     private static final int DUN_NETID = 102;
296 
297     private static final int TETHER_USB_RNDIS_NCM_FUNCTIONS = 2;
298 
299     private static final int DHCPSERVER_START_TIMEOUT_MS = 1000;
300 
301     private static final Network[] NULL_NETWORK = new Network[] {null};
302 
303     @Mock private ApplicationInfo mApplicationInfo;
304     @Mock private Context mContext;
305     @Mock private NetworkStatsManager mStatsManager;
306     @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
307     @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats;
308     @Mock private Resources mResources;
309     @Mock private TelephonyManager mTelephonyManager;
310     @Mock private UsbManager mUsbManager;
311     @Mock private WifiManager mWifiManager;
312     @Mock private CarrierConfigManager mCarrierConfigManager;
313     @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
314     @Mock private DadProxy mDadProxy;
315     @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
316     @Mock private IpNeighborMonitor mIpNeighborMonitor;
317     @Mock private IDhcpServer mDhcpServer;
318     @Mock private INetd mNetd;
319     @Mock private UserManager mUserManager;
320     @Mock private EthernetManager mEm;
321     @Mock private TetheringNotificationUpdater mNotificationUpdater;
322     @Mock private BpfCoordinator mBpfCoordinator;
323     @Mock private PackageManager mPackageManager;
324     @Mock private BluetoothAdapter mBluetoothAdapter;
325     @Mock private BluetoothPan mBluetoothPan;
326     @Mock private BluetoothPanShim mBluetoothPanShim;
327     @Mock private TetheredInterfaceRequestShim mTetheredInterfaceRequestShim;
328     @Mock private TetheringMetrics mTetheringMetrics;
329     @Mock private PrivateAddressCoordinator.Dependencies mPrivateAddressCoordinatorDependencies;
330 
331     private MockIpServerDependencies mIpServerDependencies;
332     private final MockTetheringDependencies mTetheringDependencies =
333             new MockTetheringDependencies();
334 
335     // Like so many Android system APIs, these cannot be mocked because it is marked final.
336     // We have to use the real versions.
337     private final PersistableBundle mCarrierConfig = new PersistableBundle();
338     private TestLooper mLooper;
339 
340     private Vector<Intent> mIntents;
341     private BroadcastInterceptingContext mServiceContext;
342     private MockContentResolver mContentResolver;
343     private BroadcastReceiver mBroadcastReceiver;
344     private Tethering mTethering;
345     private TestTetheringEventCallback mTetheringEventCallback;
346     private Tethering.TetherMainSM mTetherMainSM;
347     private PhoneStateListener mPhoneStateListener;
348     private InterfaceConfigurationParcel mInterfaceConfiguration;
349     private TetheringConfiguration mConfig;
350     private EntitlementManager mEntitleMgr;
351     private OffloadController mOffloadCtrl;
352     private SoftApCallback mSoftApCallback;
353     private SoftApCallback mLocalOnlyHotspotCallback;
354     private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
355     private UpstreamNetworkMonitor.EventListener mEventListener;
356     private TetheredInterfaceCallbackShim mTetheredInterfaceCallbackShim;
357     private RoutingCoordinatorManager mRoutingCoordinatorManager;
358 
359     private TestConnectivityManager mCm;
360     private boolean mForceEthernetServiceUnavailable = false;
361     private int mBinderCallingUid = TEST_CALLER_UID;
362     private boolean mTetheringWithSoftApConfigEnabled = SdkLevel.isAtLeastB();
363 
364     private class TestContext extends BroadcastInterceptingContext {
TestContext(Context base)365         TestContext(Context base) {
366             super(base);
367         }
368 
369         @Override
getApplicationInfo()370         public ApplicationInfo getApplicationInfo() {
371             return mApplicationInfo;
372         }
373 
374         @Override
getContentResolver()375         public ContentResolver getContentResolver() {
376             return mContentResolver;
377         }
378 
379         @Override
getPackageName()380         public String getPackageName() {
381             return "TetheringTest";
382         }
383 
384         @Override
getResources()385         public Resources getResources() {
386             return mResources;
387         }
388 
389         @Override
getSystemService(String name)390         public Object getSystemService(String name) {
391             if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
392             if (Context.USB_SERVICE.equals(name)) return mUsbManager;
393             if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
394             if (Context.USER_SERVICE.equals(name)) return mUserManager;
395             if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
396             if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
397             if (Context.ETHERNET_SERVICE.equals(name)) {
398                 if (mForceEthernetServiceUnavailable) return null;
399 
400                 return mEm;
401             }
402             return super.getSystemService(name);
403         }
404 
405         @Override
getPackageManager()406         public PackageManager getPackageManager() {
407             return mPackageManager;
408         }
409 
410         @Override
getSystemServiceName(Class<?> serviceClass)411         public String getSystemServiceName(Class<?> serviceClass) {
412             if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE;
413             if (ConnectivityManager.class.equals(serviceClass)) return Context.CONNECTIVITY_SERVICE;
414             return super.getSystemServiceName(serviceClass);
415         }
416     }
417 
418     public class MockIpServerDependencies extends IpServer.Dependencies {
419 
420         private int mOnDhcpServerCreatedResult = STATUS_SUCCESS;
421 
422         @Override
getDadProxy( Handler handler, InterfaceParams ifParams)423         public DadProxy getDadProxy(
424                 Handler handler, InterfaceParams ifParams) {
425             return mDadProxy;
426         }
427 
428         @Override
getRouterAdvertisementDaemon( InterfaceParams ifParams)429         public RouterAdvertisementDaemon getRouterAdvertisementDaemon(
430                 InterfaceParams ifParams) {
431             return mRouterAdvertisementDaemon;
432         }
433 
434         @Override
getInterfaceParams(String ifName)435         public InterfaceParams getInterfaceParams(String ifName) {
436             assertTrue("Non-mocked interface " + ifName,
437                     ifName.equals(TEST_RNDIS_IFNAME)
438                             || ifName.equals(TEST_WLAN_IFNAME)
439                             || ifName.equals(TEST_WLAN2_IFNAME)
440                             || ifName.equals(TEST_WIFI_IFNAME)
441                             || ifName.equals(TEST_MOBILE_IFNAME)
442                             || ifName.equals(TEST_DUN_IFNAME)
443                             || ifName.equals(TEST_P2P_IFNAME)
444                             || ifName.equals(TEST_NCM_IFNAME)
445                             || ifName.equals(TEST_ETH_IFNAME)
446                             || ifName.equals(TEST_BT_IFNAME)
447                             || ifName.equals(TEST_VIRT_IFNAME));
448             final String[] ifaces = new String[] {
449                     TEST_RNDIS_IFNAME, TEST_WLAN_IFNAME, TEST_WLAN2_IFNAME, TEST_WIFI_IFNAME,
450                     TEST_MOBILE_IFNAME, TEST_DUN_IFNAME, TEST_P2P_IFNAME, TEST_NCM_IFNAME,
451                     TEST_ETH_IFNAME, TEST_VIRT_IFNAME};
452             return new InterfaceParams(ifName,
453                     CollectionUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET,
454                     MacAddress.ALL_ZEROS_ADDRESS);
455         }
456 
457         @SuppressWarnings("DoNotCall") // Ignore warning for synchronous to call to Thread.run()
458         @Override
makeDhcpServer(String ifName, DhcpServingParamsParcel params, DhcpServerCallbacks cb)459         public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
460                 DhcpServerCallbacks cb) {
461             new Thread(() -> {
462                 try {
463                     cb.onDhcpServerCreated(mOnDhcpServerCreatedResult, mDhcpServer);
464                 } catch (RemoteException e) {
465                     fail(e.getMessage());
466                 }
467             }).run();
468         }
469 
getIpNeighborMonitor(Handler h, SharedLog l, IpNeighborMonitor.NeighborEventConsumer c)470         public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l,
471                 IpNeighborMonitor.NeighborEventConsumer c) {
472             return mIpNeighborMonitor;
473         }
474 
setOnDhcpServerCreatedResult(final int result)475         public void setOnDhcpServerCreatedResult(final int result) {
476             mOnDhcpServerCreatedResult = result;
477         }
478 
479         @Override
isFeatureEnabled(Context context, String name)480         public boolean isFeatureEnabled(Context context, String name) {
481             return mFeatureFlags.getOrDefault(name, false);
482         }
483     }
484 
485     public class MockTetheringDependencies extends TetheringDependencies {
486         ArrayList<IpServer> mAllDownstreams;
487 
488         @Override
makeBpfCoordinator( BpfCoordinator.Dependencies deps)489         public BpfCoordinator makeBpfCoordinator(
490                 BpfCoordinator.Dependencies deps) {
491             return mBpfCoordinator;
492         }
493 
494         @Override
makeOffloadHardwareInterface(Handler h, SharedLog log)495         public OffloadHardwareInterface makeOffloadHardwareInterface(Handler h, SharedLog log) {
496             return mOffloadHardwareInterface;
497         }
498 
499         @Override
makeOffloadController(Handler h, SharedLog log, OffloadController.Dependencies deps)500         public OffloadController makeOffloadController(Handler h, SharedLog log,
501                 OffloadController.Dependencies deps) {
502             mOffloadCtrl = spy(super.makeOffloadController(h, log, deps));
503             // Return real object here instead of mock because
504             // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object.
505             return mOffloadCtrl;
506         }
507 
508         @Override
makeUpstreamNetworkMonitor(Context ctx, Handler h, SharedLog log, UpstreamNetworkMonitor.EventListener listener)509         public UpstreamNetworkMonitor makeUpstreamNetworkMonitor(Context ctx, Handler h,
510                 SharedLog log, UpstreamNetworkMonitor.EventListener listener) {
511             // Use a real object instead of a mock so that some tests can use a real UNM and some
512             // can use a mock.
513             mEventListener = listener;
514             mUpstreamNetworkMonitor = spy(super.makeUpstreamNetworkMonitor(ctx, h, log, listener));
515             return mUpstreamNetworkMonitor;
516         }
517 
518         @Override
makeIPv6TetheringCoordinator( ArrayList<IpServer> notifyList, SharedLog log)519         public IPv6TetheringCoordinator makeIPv6TetheringCoordinator(
520                 ArrayList<IpServer> notifyList, SharedLog log) {
521             mAllDownstreams = notifyList;
522             return mIPv6TetheringCoordinator;
523         }
524 
525         @Override
makeIpServerDependencies()526         public IpServer.Dependencies makeIpServerDependencies() {
527             return mIpServerDependencies;
528         }
529 
530         @Override
makeEntitlementManager(Context ctx, Handler h, SharedLog log, Runnable callback)531         public EntitlementManager makeEntitlementManager(Context ctx, Handler h, SharedLog log,
532                 Runnable callback) {
533             mEntitleMgr = spy(super.makeEntitlementManager(ctx, h, log, callback));
534             return mEntitleMgr;
535         }
536 
537         @Override
getRoutingCoordinator( final Context context, SharedLog log)538         public RoutingCoordinatorManager getRoutingCoordinator(
539                 final Context context, SharedLog log) {
540             ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
541             when(mPrivateAddressCoordinatorDependencies.isFeatureEnabled(anyString()))
542                     .thenReturn(false);
543             RoutingCoordinatorService service = new RoutingCoordinatorService(
544                     getINetd(context, log),
545                             cm::getAllNetworks,
546                             mPrivateAddressCoordinatorDependencies);
547             mRoutingCoordinatorManager = spy(new RoutingCoordinatorManager(context, service));
548             return mRoutingCoordinatorManager;
549         }
550 
551         @Override
generateTetheringConfiguration(Context ctx, SharedLog log, int subId)552         public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
553                 int subId) {
554             mConfig = spy(new FakeTetheringConfiguration(ctx, log, subId));
555             return mConfig;
556         }
557 
558         @Override
getINetd(Context context, SharedLog log)559         public INetd getINetd(Context context, SharedLog log) {
560             return mNetd;
561         }
562 
563         @Override
makeTetheringLooper()564         public Looper makeTetheringLooper() {
565             return mLooper.getLooper();
566         }
567 
568         @Override
getContext()569         public Context getContext() {
570             return mServiceContext;
571         }
572 
573         @Override
getBluetoothAdapter()574         public BluetoothAdapter getBluetoothAdapter() {
575             return mBluetoothAdapter;
576         }
577 
578         @Override
makeNotificationUpdater(Context ctx, Looper looper)579         public TetheringNotificationUpdater makeNotificationUpdater(Context ctx, Looper looper) {
580             return mNotificationUpdater;
581         }
582 
583         @Override
isTetheringDenied()584         public boolean isTetheringDenied() {
585             return false;
586         }
587 
588         @Override
makeTetheringMetrics(Context ctx)589         public TetheringMetrics makeTetheringMetrics(Context ctx) {
590             return mTetheringMetrics;
591         }
592 
593         @Override
makeBluetoothPanShim(BluetoothPan pan)594         public BluetoothPanShim makeBluetoothPanShim(BluetoothPan pan) {
595             try {
596                 when(mBluetoothPanShim.requestTetheredInterface(
597                         any(), any())).thenReturn(mTetheredInterfaceRequestShim);
598             } catch (UnsupportedApiLevelException e) {
599                 fail("BluetoothPan#requestTetheredInterface is not supported");
600             }
601             return mBluetoothPanShim;
602         }
603 
604         @Override
getBinderCallingUid()605         public int getBinderCallingUid() {
606             return mBinderCallingUid;
607         }
608 
609         @Override
isTetheringWithSoftApConfigEnabled()610         public boolean isTetheringWithSoftApConfigEnabled() {
611             return mTetheringWithSoftApConfigEnabled;
612         }
613     }
614 
buildUpstreamLinkProperties(String interfaceName, boolean withIPv4, boolean withIPv6, boolean with464xlat)615     private static LinkProperties buildUpstreamLinkProperties(String interfaceName,
616             boolean withIPv4, boolean withIPv6, boolean with464xlat) {
617         final LinkProperties prop = new LinkProperties();
618         prop.setInterfaceName(interfaceName);
619 
620         if (withIPv4) {
621             prop.addLinkAddress(new LinkAddress("10.1.2.3/15"));
622             prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
623                     InetAddresses.parseNumericAddress("10.0.0.1"),
624                     interfaceName, RTN_UNICAST));
625         }
626 
627         if (withIPv6) {
628             prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2"));
629             prop.addLinkAddress(
630                     new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"),
631                             RFC7421_PREFIX_LENGTH));
632             prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0),
633                     InetAddresses.parseNumericAddress("2001:db8::1"),
634                     interfaceName, RTN_UNICAST));
635         }
636 
637         if (with464xlat) {
638             final String clatInterface = "v4-" + interfaceName;
639             final LinkProperties stackedLink = new LinkProperties();
640             stackedLink.setInterfaceName(clatInterface);
641             stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0),
642                     InetAddresses.parseNumericAddress("192.0.0.1"),
643                     clatInterface, RTN_UNICAST));
644 
645             prop.addStackedLink(stackedLink);
646         }
647 
648         return prop;
649     }
650 
buildUpstreamCapabilities(int transport, int... otherCaps)651     private static NetworkCapabilities buildUpstreamCapabilities(int transport, int... otherCaps) {
652         // TODO: add NOT_VCN_MANAGED.
653         final NetworkCapabilities nc = new NetworkCapabilities()
654                 .addTransportType(transport);
655         for (int cap : otherCaps) {
656             nc.addCapability(cap);
657         }
658         return nc;
659     }
660 
buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, boolean with464xlat)661     private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4,
662             boolean withIPv6, boolean with464xlat) {
663         return new UpstreamNetworkState(
664                 buildUpstreamLinkProperties(TEST_MOBILE_IFNAME, withIPv4, withIPv6, with464xlat),
665                 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_INTERNET),
666                 new Network(CELLULAR_NETID));
667     }
668 
buildMobileIPv4UpstreamState()669     private static UpstreamNetworkState buildMobileIPv4UpstreamState() {
670         return buildMobileUpstreamState(true, false, false);
671     }
672 
buildMobileIPv6UpstreamState()673     private static UpstreamNetworkState buildMobileIPv6UpstreamState() {
674         return buildMobileUpstreamState(false, true, false);
675     }
676 
buildMobileDualStackUpstreamState()677     private static UpstreamNetworkState buildMobileDualStackUpstreamState() {
678         return buildMobileUpstreamState(true, true, false);
679     }
680 
buildMobile464xlatUpstreamState()681     private static UpstreamNetworkState buildMobile464xlatUpstreamState() {
682         return buildMobileUpstreamState(false, true, true);
683     }
684 
buildWifiUpstreamState()685     private static UpstreamNetworkState buildWifiUpstreamState() {
686         return new UpstreamNetworkState(
687                 buildUpstreamLinkProperties(TEST_WIFI_IFNAME, true /* IPv4 */, true /* IPv6 */,
688                         false /* 464xlat */),
689                 buildUpstreamCapabilities(TRANSPORT_WIFI, NET_CAPABILITY_INTERNET),
690                 new Network(WIFI_NETID));
691     }
692 
buildDunUpstreamState()693     private static UpstreamNetworkState buildDunUpstreamState() {
694         return new UpstreamNetworkState(
695                 buildUpstreamLinkProperties(TEST_DUN_IFNAME, true /* IPv4 */, true /* IPv6 */,
696                         false /* 464xlat */),
697                 buildUpstreamCapabilities(TRANSPORT_CELLULAR, NET_CAPABILITY_DUN),
698                 new Network(DUN_NETID));
699     }
700 
701     // See FakeSettingsProvider#clearSettingsProvider() that this also needs to be called before
702     // use.
703     @BeforeClass
setupOnce()704     public static void setupOnce() {
705         FakeSettingsProvider.clearSettingsProvider();
706     }
707 
708     @Before
setUp()709     public void setUp() throws Exception {
710         MockitoAnnotations.initMocks(this);
711         when(mResources.getStringArray(R.array.config_tether_dhcp_range))
712                 .thenReturn(new String[0]);
713         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
714                 false);
715         when(mNetd.interfaceGetList())
716                 .thenReturn(new String[] {
717                         TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_WLAN2_IFNAME, TEST_RNDIS_IFNAME,
718                         TEST_P2P_IFNAME, TEST_NCM_IFNAME, TEST_ETH_IFNAME, TEST_BT_IFNAME,
719                         TEST_VIRT_IFNAME});
720         when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn("");
721         mInterfaceConfiguration = new InterfaceConfigurationParcel();
722         mInterfaceConfiguration.flags = new String[0];
723         when(mRouterAdvertisementDaemon.start())
724                 .thenReturn(true);
725         initOffloadConfiguration(OFFLOAD_HAL_VERSION_HIDL_1_0, 0 /* defaultDisabled */);
726         when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats);
727 
728         mServiceContext = new TestContext(mContext);
729         mServiceContext.setUseRegisteredHandlers(true);
730         mContentResolver = new MockContentResolver(mServiceContext);
731         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
732         setTetheringSupported(true /* supported */);
733         mIntents = new Vector<>();
734         mBroadcastReceiver = new BroadcastReceiver() {
735             @Override
736             public void onReceive(Context context, Intent intent) {
737                 mIntents.addElement(intent);
738             }
739         };
740         mServiceContext.registerReceiver(mBroadcastReceiver,
741                 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
742 
743         mCm = spy(new TestConnectivityManager(mServiceContext, mock(IConnectivityManager.class)));
744         when(mCm.getAllNetworks()).thenReturn(new Network[] {});
745 
746         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
747         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)).thenReturn(true);
748         mIpServerDependencies = spy(new MockIpServerDependencies());
749         when(mWifiManager.startTetheredHotspot(null)).thenReturn(true);
750         mTetheringWithSoftApConfigEnabled = SdkLevel.isAtLeastB();
751     }
752 
753     // In order to interact with syncSM from the test, tethering must be created in test thread.
initTetheringOnTestThread()754     private void initTetheringOnTestThread() throws Exception {
755         mLooper = new TestLooper();
756         mTethering = new Tethering(mTetheringDependencies);
757         mTetherMainSM = mTethering.getTetherMainSMForTesting();
758         verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
759         verify(mNetd).registerUnsolicitedEventListener(any());
760         verifyDefaultNetworkRequestFiled();
761         mTetheringEventCallback = registerTetheringEventCallback();
762 
763         final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
764                 ArgumentCaptor.forClass(PhoneStateListener.class);
765         verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
766                 eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
767         mPhoneStateListener = phoneListenerCaptor.getValue();
768 
769         final ArgumentCaptor<SoftApCallback> softApCallbackCaptor =
770                 ArgumentCaptor.forClass(SoftApCallback.class);
771         verify(mWifiManager).registerSoftApCallback(any(), softApCallbackCaptor.capture());
772         mSoftApCallback = softApCallbackCaptor.getValue();
773 
774         if (isAtLeastT()) {
775             final ArgumentCaptor<SoftApCallback> localOnlyCallbackCaptor =
776                     ArgumentCaptor.forClass(SoftApCallback.class);
777             verify(mWifiManager).registerLocalOnlyHotspotSoftApCallback(any(),
778                     localOnlyCallbackCaptor.capture());
779             mLocalOnlyHotspotCallback = localOnlyCallbackCaptor.getValue();
780         }
781     }
782 
setTetheringSupported(final boolean supported)783     private void setTetheringSupported(final boolean supported) {
784         Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED,
785                 supported ? 1 : 0);
786         when(mUserManager.hasUserRestriction(
787                 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported);
788         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
789                 TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION);
790         // Setup tetherable configuration.
791         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
792                 .thenReturn(new String[] {TEST_RNDIS_REGEX});
793         when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
794                 .thenReturn(new String[] {TEST_WIFI_REGEX});
795         when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
796                 .thenReturn(new String[] {TEST_P2P_REGEX});
797         when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
798                 .thenReturn(new String[] {TEST_BT_REGEX});
799         when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
800                 .thenReturn(new String[] {TEST_NCM_REGEX});
801         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)).thenReturn(true);
802         when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
803                 new int[] {TYPE_WIFI, TYPE_MOBILE_DUN});
804         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
805     }
806 
initTetheringUpstream(UpstreamNetworkState upstreamState)807     private void initTetheringUpstream(UpstreamNetworkState upstreamState) {
808         doReturn(upstreamState).when(mUpstreamNetworkMonitor).getCurrentPreferredUpstream();
809         doReturn(upstreamState).when(mUpstreamNetworkMonitor).selectPreferredUpstreamType(any());
810     }
811 
createTetheringRequest(final int type)812     private TetheringRequest createTetheringRequest(final int type) {
813         return createTetheringRequest(type, null, null, false, CONNECTIVITY_SCOPE_GLOBAL, null);
814     }
815 
createTetheringRequest(final int type, final LinkAddress localIPv4Address, final LinkAddress staticClientAddress, final boolean exempt, final int scope, final String interfaceName)816     private TetheringRequest createTetheringRequest(final int type,
817             final LinkAddress localIPv4Address, final LinkAddress staticClientAddress,
818             final boolean exempt, final int scope, final String interfaceName) {
819         TetheringRequest.Builder builder = new TetheringRequest.Builder(type)
820                 .setExemptFromEntitlementCheck(exempt)
821                 .setConnectivityScope(scope)
822                 .setShouldShowEntitlementUi(false);
823         if (localIPv4Address != null && staticClientAddress != null) {
824             builder.setStaticIpv4Addresses(localIPv4Address, staticClientAddress);
825         }
826         if (interfaceName != null) {
827             builder.setInterfaceName(interfaceName);
828         }
829         TetheringRequest request = builder.build();
830         request.setUid(TEST_CALLER_UID);
831         request.setPackageName(TEST_CALLER_PKG);
832         return request;
833     }
834 
835     @NonNull
registerTetheringEventCallback()836     private TestTetheringEventCallback registerTetheringEventCallback() {
837         TestTetheringEventCallback callback = new TestTetheringEventCallback();
838         mTethering.registerTetheringEventCallback(callback);
839         mLooper.dispatchAll();
840         // Pull the first event which is filed immediately after the callback registration.
841         callback.expectUpstreamChanged(NULL_NETWORK);
842         return callback;
843     }
844 
845     @After
tearDown()846     public void tearDown() {
847         mServiceContext.unregisterReceiver(mBroadcastReceiver);
848         FakeSettingsProvider.clearSettingsProvider();
849     }
850 
sendWifiApStateChanged(int state)851     private void sendWifiApStateChanged(int state) {
852         final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
853         intent.putExtra(EXTRA_WIFI_AP_STATE, state);
854         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
855         mLooper.dispatchAll();
856     }
857 
sendWifiApStateChanged(int state, String ifname, int ipmode)858     private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
859         final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
860         intent.putExtra(EXTRA_WIFI_AP_STATE, state);
861         intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
862         intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
863         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
864         mLooper.dispatchAll();
865     }
866 
sendStartTetheringSoftApCallback(int state, TetheringRequest request, String ifname)867     private void sendStartTetheringSoftApCallback(int state, TetheringRequest request,
868             String ifname) {
869         ArgumentCaptor<SoftApCallback> callbackCaptor =
870                 ArgumentCaptor.forClass(SoftApCallback.class);
871         verify(mWifiManager, atLeastOnce()).startTetheredHotspot(any(TetheringRequest.class),
872                 any(Executor.class), callbackCaptor.capture());
873         SoftApState softApState = mock(SoftApState.class);
874         when(softApState.getState()).thenReturn(state);
875         when(softApState.getTetheringRequest()).thenReturn(request);
876         when(softApState.getIface()).thenReturn(ifname);
877         callbackCaptor.getValue().onStateChanged(softApState);
878         mLooper.dispatchAll();
879     }
880 
verifyWifiTetheringRequested()881     private void verifyWifiTetheringRequested() {
882         if (mTetheringDependencies.isTetheringWithSoftApConfigEnabled()) {
883             verify(mWifiManager).startTetheredHotspot(any(), any(), any());
884         } else {
885             verify(mWifiManager).startTetheredHotspot(null);
886         }
887         verify(mWifiManager, never()).stopSoftAp();
888         verifyNoMoreInteractions(mWifiManager);
889     }
890 
sendSoftApEvent(int state, TetheringRequest request, String ifname)891     private void sendSoftApEvent(int state, TetheringRequest request, String ifname) {
892         if (mTetheringDependencies.isTetheringWithSoftApConfigEnabled()) {
893             sendStartTetheringSoftApCallback(state, request, ifname);
894         } else {
895             sendWifiApStateChanged(state, ifname, IFACE_IP_MODE_TETHERED);
896         }
897     }
898 
899     private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = {
900             android.Manifest.permission.ACCESS_FINE_LOCATION,
901             android.Manifest.permission.ACCESS_WIFI_STATE
902     };
903 
sendWifiP2pConnectionChanged( boolean isGroupFormed, boolean isGroupOwner, String ifname)904     private void sendWifiP2pConnectionChanged(
905             boolean isGroupFormed, boolean isGroupOwner, String ifname) {
906         WifiP2pGroup group = null;
907         WifiP2pInfo p2pInfo = new WifiP2pInfo();
908         p2pInfo.groupFormed = isGroupFormed;
909         if (isGroupFormed) {
910             p2pInfo.isGroupOwner = isGroupOwner;
911             group = mock(WifiP2pGroup.class);
912             when(group.isGroupOwner()).thenReturn(isGroupOwner);
913             when(group.getInterface()).thenReturn(ifname);
914         }
915 
916         final Intent intent = mock(Intent.class);
917         when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
918         when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo);
919         when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group);
920 
921         mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL,
922                 P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST);
923         mLooper.dispatchAll();
924     }
925 
926     // enableType:
927     // No function enabled            = -1
928     // TETHER_USB_RNDIS_FUNCTION      = 0
929     // TETHER_USB_NCM_FUNCTIONS       = 1
930     // TETHER_USB_RNDIS_NCM_FUNCTIONS = 2
tetherUsbFunctionMatches(int function, int enabledType)931     private boolean tetherUsbFunctionMatches(int function, int enabledType) {
932         if (enabledType < 0) return false;
933 
934         if (enabledType == TETHER_USB_RNDIS_NCM_FUNCTIONS) return function < enabledType;
935 
936         return function == enabledType;
937     }
938 
sendUsbBroadcast(boolean connected, boolean configured, int function)939     private void sendUsbBroadcast(boolean connected, boolean configured, int function) {
940         final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
941         intent.putExtra(USB_CONNECTED, connected);
942         intent.putExtra(USB_CONFIGURED, configured);
943         intent.putExtra(USB_FUNCTION_RNDIS,
944                 tetherUsbFunctionMatches(TETHER_USB_RNDIS_FUNCTION, function));
945         intent.putExtra(USB_FUNCTION_NCM,
946                 tetherUsbFunctionMatches(TETHER_USB_NCM_FUNCTION, function));
947         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
948         mLooper.dispatchAll();
949     }
950 
sendConfigurationChanged()951     private void sendConfigurationChanged() {
952         final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
953         mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
954         mLooper.dispatchAll();
955     }
956 
verifyDefaultNetworkRequestFiled()957     private void verifyDefaultNetworkRequestFiled() {
958         if (isAtLeastS()) {
959             verify(mCm, times(1)).registerSystemDefaultNetworkCallback(
960                     any(NetworkCallback.class), any(Handler.class));
961         } else {
962             ArgumentCaptor<NetworkRequest> reqCaptor = ArgumentCaptor.forClass(
963                     NetworkRequest.class);
964             verify(mCm, times(1)).requestNetwork(reqCaptor.capture(),
965                     any(NetworkCallback.class), any(Handler.class));
966             assertTrue(TestConnectivityManager.looksLikeDefaultRequest(reqCaptor.getValue()));
967         }
968 
969         // Ignore calls to {@link ConnectivityManager#getallNetworks}.
970         verify(mCm, atLeast(0)).getAllNetworks();
971 
972         // The default network request is only ever filed once.
973         verifyNoMoreInteractions(mCm);
974     }
975 
verifyInterfaceServingModeStarted(String ifname, boolean expectAgentEnabled)976     private void verifyInterfaceServingModeStarted(String ifname, boolean expectAgentEnabled)
977             throws Exception {
978         verify(mNetd).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
979         verify(mNetd).tetherInterfaceAdd(ifname);
980         if (expectAgentEnabled) {
981             verify(mNetd, never()).networkAddInterface(anyInt(), anyString());
982             verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString());
983         } else {
984             verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, ifname);
985             verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname),
986                     anyString(), anyString());
987         }
988     }
989 
verifyTetheringBroadcast(String ifname, String whichExtra)990     private void verifyTetheringBroadcast(String ifname, String whichExtra) {
991         // Verify that ifname is in the whichExtra array of the tether state changed broadcast.
992         final Intent bcast = mIntents.get(0);
993         assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction());
994         final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra);
995         assertTrue(ifnames.contains(ifname));
996         mIntents.remove(bcast);
997     }
998 
failingLocalOnlyHotspotLegacyApBroadcast( boolean emulateInterfaceStatusChanged)999     public void failingLocalOnlyHotspotLegacyApBroadcast(
1000             boolean emulateInterfaceStatusChanged) throws Exception {
1001         initTetheringOnTestThread();
1002         // Emulate externally-visible WifiManager effects, causing the
1003         // per-interface state machine to start up, and telling us that
1004         // hotspot mode is to be started.
1005         if (emulateInterfaceStatusChanged) {
1006             mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1007         }
1008         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
1009 
1010         // If, and only if, Tethering received an interface status changed then
1011         // it creates a IpServer and sends out a broadcast indicating that the
1012         // interface is "available".
1013         if (emulateInterfaceStatusChanged) {
1014             if (!SdkLevel.isAtLeastB()) {
1015                 // There is 1 IpServer state change event: STATE_AVAILABLE
1016                 verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
1017                 verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
1018                 verify(mWifiManager).updateInterfaceIpState(
1019                         TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1020             } else {
1021                 // Starting in B, ignore the interfaceStatusChanged
1022                 verify(mNotificationUpdater, never()).onDownstreamChanged(DOWNSTREAM_NONE);
1023                 verify(mWifiManager, never()).updateInterfaceIpState(
1024                         TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1025             }
1026         }
1027         verifyNoMoreInteractions(mNetd);
1028         verifyNoMoreInteractions(mWifiManager);
1029     }
1030 
prepareNcmTethering()1031     private void prepareNcmTethering() {
1032         // Emulate startTethering(TETHERING_NCM) called
1033         mTethering.startTethering(createTetheringRequest(TETHERING_NCM), TEST_CALLER_PKG,
1034                 null);
1035         mLooper.dispatchAll();
1036         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
1037     }
1038 
prepareUsbTethering()1039     private void prepareUsbTethering() {
1040         // Emulate pressing the USB tethering button in Settings UI.
1041         final TetheringRequest request = createTetheringRequest(TETHERING_USB);
1042         mTethering.startTethering(request, TEST_CALLER_PKG, null);
1043         mLooper.dispatchAll();
1044 
1045         assertEquals(1, mTethering.getPendingTetheringRequests().size());
1046         assertTrue(mTethering.getPendingTetheringRequests().get(0).equals(request));
1047 
1048         if (mTethering.getTetheringConfiguration().isUsingNcm()) {
1049             verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NCM);
1050             mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
1051         } else {
1052             verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
1053             mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true);
1054         }
1055 
1056     }
1057 
1058     @Test
testUsbConfiguredBroadcastStartsTethering()1059     public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
1060         initTetheringOnTestThread();
1061         UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1062         initTetheringUpstream(upstreamState);
1063         prepareUsbTethering();
1064 
1065         // This should produce no activity of any kind.
1066         verifyNoMoreInteractions(mNetd);
1067 
1068         // Pretend we then receive USB configured broadcast.
1069         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
1070         // Now we should see the start of tethering mechanics (in this case:
1071         // tetherMatchingInterfaces() which starts by fetching all interfaces).
1072         verify(mNetd, times(1)).interfaceGetList();
1073 
1074         // Event callback should receive selected upstream
1075         verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
1076         mTetheringEventCallback.expectUpstreamChanged(upstreamState.network);
1077     }
1078 
1079     @Test
failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged()1080     public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception {
1081         failingLocalOnlyHotspotLegacyApBroadcast(true);
1082     }
1083 
1084     @Test
failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged()1085     public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception {
1086         failingLocalOnlyHotspotLegacyApBroadcast(false);
1087     }
1088 
isTetheringNetworkAgentFeatureEnabled()1089     private boolean isTetheringNetworkAgentFeatureEnabled() {
1090         return isAtLeastV() && mFeatureFlags.getOrDefault(TETHERING_LOCAL_NETWORK_AGENT, false);
1091     }
1092 
verifyStopHotpot(boolean isLocalOnly)1093     private void verifyStopHotpot(boolean isLocalOnly) throws Exception {
1094         verify(mNetd).tetherApplyDnsInterfaces();
1095         verify(mNetd).tetherInterfaceRemove(TEST_WLAN_IFNAME);
1096         if (!isLocalOnly && isTetheringNetworkAgentFeatureEnabled()) {
1097             verify(mNetd, never()).networkRemoveInterface(anyInt(), anyString());
1098         } else {
1099             verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
1100         }
1101         // interfaceSetCfg() called once for enabling and twice disabling IPv4.
1102         verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
1103         verify(mNetd).tetherStop();
1104         verify(mNetd).ipfwdDisableForwarding(TETHERING_NAME);
1105         verify(mWifiManager, times(3)).updateInterfaceIpState(
1106                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1107         verifyNoMoreInteractions(mNetd);
1108         verifyNoMoreInteractions(mWifiManager);
1109         // Asking for the last error after the per-interface state machine
1110         // has been reaped yields an unknown interface error.
1111         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_WLAN_IFNAME));
1112     }
1113 
verifyStartHotspot()1114     private void verifyStartHotspot() throws Exception {
1115         verifyStartHotspot(false /* isLocalOnly */);
1116     }
1117 
verifyStartHotspot(boolean isLocalOnly)1118     private void verifyStartHotspot(boolean isLocalOnly) throws Exception {
1119         final boolean expectAgentEnabled = !isLocalOnly && isTetheringNetworkAgentFeatureEnabled();
1120         verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME, expectAgentEnabled);
1121         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
1122         verify(mWifiManager).updateInterfaceIpState(
1123                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
1124 
1125         verify(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
1126         verify(mNetd).tetherStartWithConfiguration(any());
1127         verifyNoMoreInteractions(mNetd);
1128 
1129         final int expectedState = isLocalOnly ? IFACE_IP_MODE_LOCAL_ONLY : IFACE_IP_MODE_TETHERED;
1130         verify(mWifiManager).updateInterfaceIpState(TEST_WLAN_IFNAME, expectedState);
1131         verifyNoMoreInteractions(mWifiManager);
1132 
1133         verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks();
1134         if (isLocalOnly) {
1135             // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY.
1136             verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
1137         } else {
1138             // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED.
1139             verify(mNotificationUpdater).onDownstreamChanged(DOWNSTREAM_NONE);
1140             verify(mNotificationUpdater).onDownstreamChanged(eq(1 << TETHERING_WIFI));
1141         }
1142     }
1143 
workingLocalOnlyHotspotEnrichedApBroadcast( boolean emulateInterfaceStatusChanged)1144     public void workingLocalOnlyHotspotEnrichedApBroadcast(
1145             boolean emulateInterfaceStatusChanged) throws Exception {
1146         initTetheringOnTestThread();
1147         // Emulate externally-visible WifiManager effects, causing the
1148         // per-interface state machine to start up, and telling us that
1149         // hotspot mode is to be started.
1150         if (emulateInterfaceStatusChanged) {
1151             mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
1152         }
1153         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
1154 
1155         verifyStartHotspot(true /* isLocalOnly */);
1156         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
1157 
1158         // Emulate externally-visible WifiManager effects, when hotspot mode
1159         // is being torn down.
1160         sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
1161         mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
1162         mLooper.dispatchAll();
1163 
1164         verifyStopHotpot(true /* isLocalOnly */);
1165     }
1166 
1167     /**
1168      * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator.
1169      */
sendIPv6TetherUpdates(UpstreamNetworkState upstreamState)1170     private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) {
1171         // IPv6TetheringCoordinator must have been notified of downstream
1172         for (IpServer ipSrv : mTetheringDependencies.mAllDownstreams) {
1173             UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false);
1174             ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0,
1175                     upstreamState.linkProperties.isIpv6Provisioned()
1176                             ? ipv6OnlyState.linkProperties
1177                             : null);
1178             break;
1179         }
1180         mLooper.dispatchAll();
1181     }
1182 
runUsbTethering(UpstreamNetworkState upstreamState)1183     private void runUsbTethering(UpstreamNetworkState upstreamState) {
1184         initTetheringUpstream(upstreamState);
1185         prepareUsbTethering();
1186         if (mTethering.getTetheringConfiguration().isUsingNcm()) {
1187             sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION);
1188             verify(mIPv6TetheringCoordinator).addActiveDownstream(
1189                     argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_NCM_IFNAME)),
1190                     eq(IpServer.STATE_TETHERED));
1191         } else {
1192             sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
1193             verify(mIPv6TetheringCoordinator).addActiveDownstream(
1194                     argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_RNDIS_IFNAME)),
1195                     eq(IpServer.STATE_TETHERED));
1196         }
1197 
1198     }
1199 
assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName)1200     private void assertSetIfaceToDadProxy(final int numOfCalls, final String ifaceName) {
1201         if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R || "S".equals(Build.VERSION.CODENAME)
1202                     || "T".equals(Build.VERSION.CODENAME)) {
1203             verify(mDadProxy, times(numOfCalls)).setUpstreamIface(
1204                      argThat(ifaceParams  -> ifaceName.equals(ifaceParams.name)));
1205         }
1206     }
1207 
1208     @Test
workingMobileUsbTethering_IPv4()1209     public void workingMobileUsbTethering_IPv4() throws Exception {
1210         initTetheringOnTestThread();
1211         UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1212         runUsbTethering(upstreamState);
1213 
1214         verify(mRoutingCoordinatorManager, times(1))
1215                 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1216 
1217         sendIPv6TetherUpdates(upstreamState);
1218         assertSetIfaceToDadProxy(0 /* numOfCalls */, "" /* ifaceName */);
1219         verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
1220         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1221                 any(), any());
1222     }
1223 
1224     @Test
workingMobileUsbTethering_IPv4LegacyDhcp()1225     public void workingMobileUsbTethering_IPv4LegacyDhcp() throws Exception {
1226         initTetheringOnTestThread();
1227         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
1228                 true);
1229         sendConfigurationChanged();
1230         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
1231         runUsbTethering(upstreamState);
1232         sendIPv6TetherUpdates(upstreamState);
1233 
1234         verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
1235     }
1236 
1237     @Test
workingMobileUsbTethering_IPv6()1238     public void workingMobileUsbTethering_IPv6() throws Exception {
1239         initTetheringOnTestThread();
1240         UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
1241         runUsbTethering(upstreamState);
1242 
1243         verify(mRoutingCoordinatorManager, times(1))
1244                 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1245 
1246         sendIPv6TetherUpdates(upstreamState);
1247         // TODO: add interfaceParams to compare in verify.
1248         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
1249         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
1250         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1251     }
1252 
1253     @Test
workingMobileUsbTethering_DualStack()1254     public void workingMobileUsbTethering_DualStack() throws Exception {
1255         initTetheringOnTestThread();
1256         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
1257         runUsbTethering(upstreamState);
1258 
1259         verify(mRoutingCoordinatorManager, times(1))
1260                 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1261         verify(mRouterAdvertisementDaemon, times(1)).start();
1262         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1263                 any(), any());
1264 
1265         sendIPv6TetherUpdates(upstreamState);
1266         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
1267         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
1268         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1269     }
1270 
1271     @Test
workingMobileUsbTethering_MultipleUpstreams()1272     public void workingMobileUsbTethering_MultipleUpstreams() throws Exception {
1273         initTetheringOnTestThread();
1274         UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState();
1275         runUsbTethering(upstreamState);
1276 
1277         verify(mRoutingCoordinatorManager, times(1))
1278                 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_XLAT_MOBILE_IFNAME);
1279         verify(mRoutingCoordinatorManager, times(1))
1280                 .addInterfaceForward(TEST_RNDIS_IFNAME, TEST_MOBILE_IFNAME);
1281         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1282                 any(), any());
1283 
1284         sendIPv6TetherUpdates(upstreamState);
1285         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
1286         verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
1287         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
1288     }
1289 
1290     @Test
workingMobileUsbTethering_v6Then464xlat()1291     public void workingMobileUsbTethering_v6Then464xlat() throws Exception {
1292         initTetheringOnTestThread();
1293         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
1294                 TetheringConfiguration.TETHER_USB_NCM_FUNCTION);
1295         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
1296                 .thenReturn(new String[] {TEST_NCM_REGEX});
1297         sendConfigurationChanged();
1298 
1299         // Setup IPv6
1300         UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
1301         runUsbTethering(upstreamState);
1302 
1303         verify(mRoutingCoordinatorManager, times(1))
1304                 .addInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME);
1305         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1306                 any(), any());
1307 
1308         // Then 464xlat comes up
1309         upstreamState = buildMobile464xlatUpstreamState();
1310         initTetheringUpstream(upstreamState);
1311 
1312         // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
1313         mEventListener.onUpstreamEvent(UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES,
1314                 upstreamState);
1315         mLooper.dispatchAll();
1316 
1317         // Forwarding is added for 464xlat
1318         verify(mRoutingCoordinatorManager, times(1))
1319                 .addInterfaceForward(TEST_NCM_IFNAME, TEST_XLAT_MOBILE_IFNAME);
1320         // Forwarding was not re-added for v6 (still times(1))
1321         verify(mRoutingCoordinatorManager, times(1))
1322                 .addInterfaceForward(TEST_NCM_IFNAME, TEST_MOBILE_IFNAME);
1323         // DHCP not restarted on downstream (still times(1))
1324         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
1325                 any(), any());
1326     }
1327 
1328     @Test
configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes()1329     public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception {
1330         initTetheringOnTestThread();
1331         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
1332         sendConfigurationChanged();
1333 
1334         // Setup IPv6
1335         final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState();
1336         runUsbTethering(upstreamState);
1337 
1338         // UpstreamNetworkMonitor should choose upstream automatically
1339         // (in this specific case: choose the default network).
1340         verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
1341         verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
1342 
1343         mTetheringEventCallback.expectUpstreamChanged(upstreamState.network);
1344     }
1345 
verifyDisableTryCellWhenTetheringStop(InOrder inOrder)1346     private void verifyDisableTryCellWhenTetheringStop(InOrder inOrder) {
1347         runStopUSBTethering();
1348         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1349     }
1350 
upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi)1351     private void upstreamSelectionTestCommon(final boolean automatic, InOrder inOrder,
1352             TestNetworkAgent mobile, TestNetworkAgent wifi) throws Exception {
1353         // Enable automatic upstream selection.
1354         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic);
1355         sendConfigurationChanged();
1356         mLooper.dispatchAll();
1357 
1358         // Start USB tethering with no current upstream.
1359         prepareUsbTethering();
1360         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
1361         inOrder.verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks();
1362         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1363 
1364         // Pretend cellular connected and expect the upstream to be set.
1365         mobile.fakeConnect();
1366         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST);
1367         mLooper.dispatchAll();
1368         mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
1369 
1370         // Switch upstream to wifi.
1371         wifi.fakeConnect();
1372         mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST);
1373         mLooper.dispatchAll();
1374         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1375         mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
1376     }
1377 
verifyAutomaticUpstreamSelection(boolean configAutomatic)1378     private void verifyAutomaticUpstreamSelection(boolean configAutomatic) throws Exception {
1379         initTetheringOnTestThread();
1380         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1381         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1382         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1383         // Enable automatic upstream selection.
1384         upstreamSelectionTestCommon(configAutomatic, inOrder, mobile, wifi);
1385 
1386         // This code has historically been racy, so test different orderings of CONNECTIVITY_ACTION
1387         // broadcasts and callbacks, and add mLooper.dispatchAll() calls between the two.
1388         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1389 
1390         // Switch upstreams a few times.
1391         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll);
1392         mLooper.dispatchAll();
1393         mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
1394 
1395         mCm.makeDefaultNetwork(wifi, BROADCAST_FIRST, doDispatchAll);
1396         mLooper.dispatchAll();
1397         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1398         mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
1399 
1400         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1401         mLooper.dispatchAll();
1402         mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
1403 
1404         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1405         mLooper.dispatchAll();
1406         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1407         mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
1408 
1409         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll);
1410         mLooper.dispatchAll();
1411         mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
1412 
1413         // Wifi disconnecting should not have any affect since it's not the current upstream.
1414         wifi.fakeDisconnect();
1415         mLooper.dispatchAll();
1416         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1417 
1418         // Lose and regain upstream.
1419         assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
1420                 .hasIPv4Address());
1421         mCm.makeDefaultNetwork(null, BROADCAST_FIRST, doDispatchAll);
1422         mLooper.dispatchAll();
1423         mobile.fakeDisconnect();
1424         mLooper.dispatchAll();
1425         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1426         mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
1427 
1428         mobile = new TestNetworkAgent(mCm, buildMobile464xlatUpstreamState());
1429         mobile.fakeConnect();
1430         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST, doDispatchAll);
1431         mLooper.dispatchAll();
1432         mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
1433 
1434         // Check the IP addresses to ensure that the upstream is indeed not the same as the previous
1435         // mobile upstream, even though the netId is (unrealistically) the same.
1436         assertFalse(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
1437                 .hasIPv4Address());
1438 
1439         // Lose and regain upstream again.
1440         mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll);
1441         mobile.fakeDisconnect();
1442         mLooper.dispatchAll();
1443         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1444         mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
1445 
1446         mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1447         mobile.fakeConnect();
1448         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, doDispatchAll);
1449         mLooper.dispatchAll();
1450         mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
1451 
1452         assertTrue(mUpstreamNetworkMonitor.getCurrentPreferredUpstream().linkProperties
1453                 .hasIPv4Address());
1454 
1455         // Check that the code does not crash if onLinkPropertiesChanged is received after onLost.
1456         mobile.fakeDisconnect();
1457         mobile.sendLinkProperties();
1458         mLooper.dispatchAll();
1459 
1460         verifyDisableTryCellWhenTetheringStop(inOrder);
1461     }
1462 
1463     @Test
testAutomaticUpstreamSelection()1464     public void testAutomaticUpstreamSelection() throws Exception {
1465         verifyAutomaticUpstreamSelection(true /* configAutomatic */);
1466     }
1467 
1468     @Test
1469     @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
testAutomaticUpstreamSelectionWithConfigDisabled()1470     public void testAutomaticUpstreamSelectionWithConfigDisabled() throws Exception {
1471         // Expect that automatic config can't disable the automatic mode because automatic mode
1472         // is always enabled on U+ device.
1473         verifyAutomaticUpstreamSelection(false /* configAutomatic */);
1474     }
1475 
1476     @Test
1477     @IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
testLegacyUpstreamSelection()1478     public void testLegacyUpstreamSelection() throws Exception {
1479         initTetheringOnTestThread();
1480         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1481         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1482         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1483         // Enable legacy upstream selection.
1484         upstreamSelectionTestCommon(false, inOrder, mobile, wifi);
1485 
1486         // Wifi disconnecting and the default network switch to mobile, the upstream should also
1487         // switch to mobile.
1488         wifi.fakeDisconnect();
1489         mLooper.dispatchAll();
1490         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST, null);
1491         mLooper.dispatchAll();
1492         mTetheringEventCallback.expectUpstreamChanged(mobile.networkId);
1493 
1494         wifi.fakeConnect();
1495         mLooper.dispatchAll();
1496         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST, null);
1497         mLooper.dispatchAll();
1498         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1499         mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
1500 
1501         verifyDisableTryCellWhenTetheringStop(inOrder);
1502     }
1503 
verifyWifiUpstreamAndUnregisterDunCallback(@onNull final InOrder inOrder, @NonNull final TestNetworkAgent wifi, @NonNull final NetworkCallback currentDunCallack)1504     private void verifyWifiUpstreamAndUnregisterDunCallback(@NonNull final InOrder inOrder,
1505             @NonNull final TestNetworkAgent wifi, @NonNull final NetworkCallback currentDunCallack)
1506             throws Exception {
1507         assertNotNull(currentDunCallack);
1508 
1509         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1510         inOrder.verify(mCm).unregisterNetworkCallback(eq(currentDunCallack));
1511         mTetheringEventCallback.expectUpstreamChanged(wifi.networkId);
1512         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1513     }
1514 
1515     @Nullable
verifyDunUpstream(@onNull final InOrder inOrder, @NonNull final TestNetworkAgent dun, final boolean needToRequestNetwork)1516     private NetworkCallback verifyDunUpstream(@NonNull final InOrder inOrder,
1517             @NonNull final TestNetworkAgent dun, final boolean needToRequestNetwork)
1518             throws Exception {
1519         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1520         ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class);
1521         NetworkCallback dunNetworkCallback = null;
1522         if (needToRequestNetwork) {
1523             inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(),
1524                     captor.capture());
1525             dunNetworkCallback = captor.getValue();
1526         }
1527         mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
1528         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1529         dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
1530         mLooper.dispatchAll();
1531         mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
1532 
1533         if (needToRequestNetwork) {
1534             assertNotNull(dunNetworkCallback);
1535         } else {
1536             assertNull(dunNetworkCallback);
1537         }
1538 
1539         return dunNetworkCallback;
1540     }
1541 
1542     // Overall test coverage:
1543     // - verifyChooseDunUpstreamByAutomaticMode: common, test#1, test#2
1544     // - testChooseDunUpstreamByAutomaticMode_defaultNetworkWifi: test#3, test#4
1545     // - testChooseDunUpstreamByAutomaticMode_loseDefaultNetworkWifi: test#5
1546     // - testChooseDunUpstreamByAutomaticMode_defaultNetworkCell: test#5, test#7
1547     // - testChooseDunUpstreamByAutomaticMode_loseAndRegainDun: test#8
1548     // - testChooseDunUpstreamByAutomaticMode_switchDefaultFromWifiToCell: test#9, test#10
1549     //
1550     // Overall test cases:
1551     // +-------+-------+-------+-------+-------+
1552     // | Test  | WiFi  | Cellu |  Dun  | Expec |
1553     // | Case  |       | alr   |       | ted   |
1554     // |   #   |       |       |       | Upstr |
1555     // |       |       |       |       | eam   |
1556     // +-------+-------+-------+-------+-------+
1557     // |   -   |       |       |       |   -   | --+
1558     // +-------+-------+-------+-------+-------+   |
1559     // |   -   |       |   V   |       |   -   |   |
1560     // +-------+-------+-------+-------+-------+   |
1561     // |   -   |       |   V   |   O   |  Dun  |   +-- chooseDunUpstreamTestCommon
1562     // +-------+-------+-------+-------+-------+   |
1563     // |   -   |   V   |   O   |   O   |  WiFi |   |
1564     // +-------+-------+-------+-------+-------+   |
1565     // |   -   |   V   |   O   |       |  WiFi | --+
1566     // +-------+-------+-------+-------+-------+
1567     // |       |   O   |   V   |       |   -   |
1568     // |   1   +-------+-------+-------+-------+
1569     // |       |   O   |   V   |   O   |  Dun  |
1570     // +-------+-------+-------+-------+-------+
1571     // |       |   O   |   V   |       |   -   |
1572     // |   2   +-------+-------+-------+-------+
1573     // |       |   O   |   V   |   O   |  Dun  |
1574     // +-------+-------+-------+-------+-------+
1575     // |   3   |   V   |   O   |       |  WiFi |
1576     // +-------+-------+-------+-------+-------+
1577     // |   4   |   V   |       |       |  WiFi |
1578     // +-------+-------+-------+-------+-------+
1579     // |   5   |       |       |   O   |  Dun  |
1580     // +-------+-------+-------+-------+-------+
1581     // |   6   |       |   V   |   O   |  Dun  |
1582     // +-------+-------+-------+-------+-------+
1583     // |   7   |       |       |   O   |  Dun  |
1584     // +-------+-------+-------+-------+-------+
1585     // |       |       |       |       |   -   |
1586     // |   8   +-------+-------+-------+-------+
1587     // |       |       |       |   O   |  Dun  |
1588     // +-------+-------+-------+-------+-------+
1589     // |       |   V   |       |   O   |  WiFi |
1590     // |   9   +-------+-------+-------+-------+
1591     // |       |   V   |       |       |  WiFi |
1592     // +-------+-------+-------+-------+-------+
1593     // |       |   O   |   V   |       |   -   |
1594     // |   10  +-------+-------+-------+-------+
1595     // |       |   O   |   V   |   O   |  Dun  |
1596     // +-------+-------+-------+-------+-------+
1597     //
1598     // Annotation:
1599     // 1. "V" means that the given network is connected and it is default network.
1600     // 2. "O" means that the given network is connected and it is not default network.
1601     //
1602 
1603     // Test case:
1604     // +-------+-------+-------+-------+-------+
1605     // | Test  | WiFi  | Cellu |  Dun  | Expec |
1606     // | Case  |       | alr   |       | ted   |
1607     // |   #   |       |       |       | Upstr |
1608     // |       |       |       |       | eam   |
1609     // +-------+-------+-------+-------+-------+
1610     // |   -   |       |       |       |   -   | --+
1611     // +-------+-------+-------+-------+-------+   |
1612     // |   -   |       |   V   |       |   -   |   |
1613     // +-------+-------+-------+-------+-------+   |
1614     // |   -   |       |   V   |   O   |  Dun  |   +-- chooseDunUpstreamTestCommon
1615     // +-------+-------+-------+-------+-------+   |
1616     // |   -   |   V   |   O   |   O   |  WiFi |   |
1617     // +-------+-------+-------+-------+-------+   |
1618     // |   -   |   V   |   O   |       |  WiFi | --+
1619     // +-------+-------+-------+-------+-------+
1620     // |       |   O   |   V   |       |   -   |
1621     // |   1   +-------+-------+-------+-------+
1622     // |       |   O   |   V   |   O   |  Dun  |
1623     // +-------+-------+-------+-------+-------+
1624     // |       |   O   |   V   |       |   -   |
1625     // |   2   +-------+-------+-------+-------+
1626     // |       |   O   |   V   |   O   |  Dun  |
1627     // +-------+-------+-------+-------+-------+
1628     //
verifyChooseDunUpstreamByAutomaticMode(boolean configAutomatic)1629     private void verifyChooseDunUpstreamByAutomaticMode(boolean configAutomatic) throws Exception {
1630         initTetheringOnTestThread();
1631         // Enable automatic upstream selection.
1632         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1633         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1634         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1635         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1636         chooseDunUpstreamTestCommon(configAutomatic, inOrder, mobile, wifi, dun);
1637 
1638         // [1] When default network switch to mobile and wifi is connected (may have low signal),
1639         // automatic mode would request dun again and choose it as upstream.
1640         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1641         mLooper.dispatchAll();
1642         verifyDunUpstream(inOrder, dun, true /* needToRequestNetwork */);
1643 
1644         // [2] Lose and regain upstream again.
1645         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1646         dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
1647         mLooper.dispatchAll();
1648         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1649         mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
1650         inOrder.verify(mCm, never()).unregisterNetworkCallback(any(NetworkCallback.class));
1651         dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
1652         mLooper.dispatchAll();
1653         mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
1654 
1655         verifyDisableTryCellWhenTetheringStop(inOrder);
1656     }
1657 
1658     @Test
testChooseDunUpstreamByAutomaticMode()1659     public void testChooseDunUpstreamByAutomaticMode() throws Exception {
1660         verifyChooseDunUpstreamByAutomaticMode(true /* configAutomatic */);
1661     }
1662 
1663     // testChooseDunUpstreamByAutomaticMode_* doesn't verify configAutomatic:false because no
1664     // matter |configAutomatic| set to true or false, the result always be automatic mode. We
1665     // just need one test to make sure this behavior. Don't need to test this configuration
1666     // in all tests.
1667     @Test
1668     @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
testChooseDunUpstreamByAutomaticModeWithConfigDisabled()1669     public void testChooseDunUpstreamByAutomaticModeWithConfigDisabled() throws Exception {
1670         verifyChooseDunUpstreamByAutomaticMode(false /* configAutomatic */);
1671     }
1672 
1673     // Test case:
1674     // +-------+-------+-------+-------+-------+
1675     // | Test  | WiFi  | Cellu |  Dun  | Expec |
1676     // | Case  |       | alr   |       | ted   |
1677     // |   #   |       |       |       | Upstr |
1678     // |       |       |       |       | eam   |
1679     // +-------+-------+-------+-------+-------+
1680     // |   -   |   O   |   V   |   O   |  Dun  |
1681     // +-------+-------+-------+-------+-------+
1682     // |   3   |   V   |   O   |       |  WiFi |
1683     // +-------+-------+-------+-------+-------+
1684     // |   4   |   V   |       |       |  WiFi |
1685     // +-------+-------+-------+-------+-------+
1686     //
1687     // See verifyChooseDunUpstreamByAutomaticMode for the annotation.
1688     //
1689     @Test
testChooseDunUpstreamByAutomaticMode_defaultNetworkWifi()1690     public void testChooseDunUpstreamByAutomaticMode_defaultNetworkWifi() throws Exception {
1691         initTetheringOnTestThread();
1692         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1693         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1694         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1695         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1696         final NetworkCallback dunNetworkCallback1 = setupDunUpstreamTest(
1697                 true /* configAutomatic */, inOrder);
1698 
1699         // When wifi connected, unregister dun request and choose wifi as upstream.
1700         wifi.fakeConnect();
1701         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1702         mLooper.dispatchAll();
1703         verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback1);
1704 
1705         // When default network switch to mobile and wifi is connected (may have low signal),
1706         // automatic mode would request dun again and choose it as upstream.
1707         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1708         mLooper.dispatchAll();
1709         final NetworkCallback dunNetworkCallback2 = verifyDunUpstream(inOrder, dun,
1710                 true /* needToRequestNetwork */);
1711 
1712         // [3] When default network switch to wifi and mobile is still connected,
1713         // unregister dun request and choose wifi as upstream.
1714         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1715         mLooper.dispatchAll();
1716         verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback2);
1717 
1718         // [4] When mobile is disconnected, keep wifi as upstream.
1719         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1720         mobile.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
1721         mLooper.dispatchAll();
1722         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1723 
1724         verifyDisableTryCellWhenTetheringStop(inOrder);
1725     }
1726 
1727     // Test case:
1728     // +-------+-------+-------+-------+-------+
1729     // | Test  | WiFi  | Cellu |  Dun  | Expec |
1730     // | Case  |       | alr   |       | ted   |
1731     // |   #   |       |       |       | Upstr |
1732     // |       |       |       |       | eam   |
1733     // +-------+-------+-------+-------+-------+
1734     // |   -   |   V   |       |       |  WiFi |
1735     // +-------+-------+-------+-------+-------+
1736     // |   5   |       |       |   O   |  Dun  |
1737     // +-------+-------+-------+-------+-------+
1738     //
1739     // See verifyChooseDunUpstreamByAutomaticMode for the annotation.
1740     //
1741     @Test
testChooseDunUpstreamByAutomaticMode_loseDefaultNetworkWifi()1742     public void testChooseDunUpstreamByAutomaticMode_loseDefaultNetworkWifi() throws Exception {
1743         initTetheringOnTestThread();
1744         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1745         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1746         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1747         final NetworkCallback dunNetworkCallback = setupDunUpstreamTest(
1748                 true /* configAutomatic */, inOrder);
1749 
1750         // When wifi connected, unregister dun request and choose wifi as upstream.
1751         wifi.fakeConnect();
1752         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1753         mLooper.dispatchAll();
1754         verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback);
1755 
1756         // [5] When wifi is disconnected, automatic mode would request dun again and choose it
1757         // as upstream.
1758         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1759         mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll);
1760         wifi.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
1761         mLooper.dispatchAll();
1762         verifyDunUpstream(inOrder, dun, true /* needToRequestNetwork */);
1763 
1764         verifyDisableTryCellWhenTetheringStop(inOrder);
1765     }
1766 
1767     // Test case:
1768     // +-------+-------+-------+-------+-------+
1769     // | Test  | WiFi  | Cellu |  Dun  | Expec |
1770     // | Case  |       | alr   |       | ted   |
1771     // |   #   |       |       |       | Upstr |
1772     // |       |       |       |       | eam   |
1773     // +-------+-------+-------+-------+-------+
1774     // |   -   |       |       |   O   |  Dun  |
1775     // +-------+-------+-------+-------+-------+
1776     // |   6   |       |   V   |   O   |  Dun  |
1777     // +-------+-------+-------+-------+-------+
1778     // |   7   |       |       |   O   |  Dun  |
1779     // +-------+-------+-------+-------+-------+
1780     //
1781     // See verifyChooseDunUpstreamByAutomaticMode for the annotation.
1782     //
1783     @Test
testChooseDunUpstreamByAutomaticMode_defaultNetworkCell()1784     public void testChooseDunUpstreamByAutomaticMode_defaultNetworkCell() throws Exception {
1785         initTetheringOnTestThread();
1786         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1787         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1788         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1789         setupDunUpstreamTest(true /* configAutomatic */, inOrder);
1790 
1791         // Pretend dun connected and expect choose dun as upstream.
1792         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1793         dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
1794         mLooper.dispatchAll();
1795         mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
1796 
1797         // [6] When mobile is connected and default network switch to mobile, keep dun as upstream.
1798         mobile.fakeConnect();
1799         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1800         mLooper.dispatchAll();
1801         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1802 
1803         // [7] When mobile is disconnected, keep dun as upstream.
1804         mCm.makeDefaultNetwork(null, CALLBACKS_FIRST, doDispatchAll);
1805         mobile.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
1806         mLooper.dispatchAll();
1807         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1808 
1809         verifyDisableTryCellWhenTetheringStop(inOrder);
1810     }
1811 
1812     // Test case:
1813     // +-------+-------+-------+-------+-------+
1814     // | Test  | WiFi  | Cellu |  Dun  | Expec |
1815     // | Case  |       | alr   |       | ted   |
1816     // |   #   |       |       |       | Upstr |
1817     // |       |       |       |       | eam   |
1818     // +-------+-------+-------+-------+-------+
1819     // |   -   |       |       |   O   |  Dun  |
1820     // +-------+-------+-------+-------+-------+
1821     // |       |       |       |       |   -   |
1822     // |   8   +-------+-------+-------+-------+
1823     // |       |       |       |   O   |  Dun  |
1824     // +-------+-------+-------+-------+-------+
1825     //
1826     // See verifyChooseDunUpstreamByAutomaticMode for the annotation.
1827     //
1828     @Test
testChooseDunUpstreamByAutomaticMode_loseAndRegainDun()1829     public void testChooseDunUpstreamByAutomaticMode_loseAndRegainDun() throws Exception {
1830         initTetheringOnTestThread();
1831         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1832         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1833         setupDunUpstreamTest(true /* configAutomatic */, inOrder);
1834 
1835         // Pretend dun connected and expect choose dun as upstream.
1836         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1837         dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
1838         mLooper.dispatchAll();
1839         mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
1840 
1841         // [8] Lose and regain upstream again.
1842         dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
1843         mLooper.dispatchAll();
1844         verifyDunUpstream(inOrder, dun, false /* needToRequestNetwork */);
1845 
1846         verifyDisableTryCellWhenTetheringStop(inOrder);
1847     }
1848 
1849     // Test case:
1850     // +-------+-------+-------+-------+-------+
1851     // | Test  | WiFi  | Cellu |  Dun  | Expec |
1852     // | Case  |       | alr   |       | ted   |
1853     // |   #   |       |       |       | Upstr |
1854     // |       |       |       |       | eam   |
1855     // +-------+-------+-------+-------+-------+
1856     // |   -   |       |       |   O   |  Dun  |
1857     // +-------+-------+-------+-------+-------+
1858     // |       |   V   |       |   O   |  WiFi |
1859     // |   9   +-------+-------+-------+-------+
1860     // |       |   V   |       |       |  WiFi |
1861     // +-------+-------+-------+-------+-------+
1862     // |       |   O   |   V   |       |   -   |
1863     // |   10  +-------+-------+-------+-------+
1864     // |       |   O   |   V   |   O   |  Dun  |
1865     // +-------+-------+-------+-------+-------+
1866     //
1867     // See verifyChooseDunUpstreamByAutomaticMode for the annotation.
1868     //
1869     @Test
testChooseDunUpstreamByAutomaticMode_switchDefaultFromWifiToCell()1870     public void testChooseDunUpstreamByAutomaticMode_switchDefaultFromWifiToCell()
1871             throws Exception {
1872         initTetheringOnTestThread();
1873         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1874         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1875         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1876         final InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1877         final NetworkCallback dunNetworkCallback = setupDunUpstreamTest(
1878                 true /* configAutomatic */, inOrder);
1879 
1880         // Pretend dun connected and expect choose dun as upstream.
1881         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1882         dun.fakeConnect(CALLBACKS_FIRST, doDispatchAll);
1883         mLooper.dispatchAll();
1884         mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
1885 
1886         // [9] When wifi is connected and default network switch to wifi, unregister dun request
1887         // and choose wifi as upstream. When dun is disconnected, keep wifi as upstream.
1888         wifi.fakeConnect();
1889         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1890         mLooper.dispatchAll();
1891         verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback);
1892         dun.fakeDisconnect(CALLBACKS_FIRST, doDispatchAll);
1893         mLooper.dispatchAll();
1894         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1895 
1896         // [10] When mobile and mobile are connected and default network switch to mobile
1897         // (may have low signal), automatic mode would request dun again and choose it as
1898         // upstream.
1899         mobile.fakeConnect();
1900         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1901         mLooper.dispatchAll();
1902         verifyDunUpstream(inOrder, dun, true /* needToRequestNetwork */);
1903 
1904         verifyDisableTryCellWhenTetheringStop(inOrder);
1905     }
1906 
1907     @Test
1908     @IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
testChooseDunUpstreamByLegacyMode()1909     public void testChooseDunUpstreamByLegacyMode() throws Exception {
1910         initTetheringOnTestThread();
1911         // Enable Legacy upstream selection.
1912         TestNetworkAgent mobile = new TestNetworkAgent(mCm, buildMobileDualStackUpstreamState());
1913         TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
1914         TestNetworkAgent dun = new TestNetworkAgent(mCm, buildDunUpstreamState());
1915         InOrder inOrder = inOrder(mCm, mUpstreamNetworkMonitor);
1916         chooseDunUpstreamTestCommon(false, inOrder, mobile, wifi, dun);
1917 
1918         // Legacy mode would keep use wifi as upstream (because it has higher priority in the
1919         // list).
1920         mCm.makeDefaultNetwork(mobile, CALLBACKS_FIRST);
1921         mLooper.dispatchAll();
1922         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1923         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1924         // BUG: when wifi disconnect, the dun request would not be filed again because wifi is
1925         // no longer be default network which do not have CONNECTIVIY_ACTION broadcast.
1926         wifi.fakeDisconnect();
1927         mLooper.dispatchAll();
1928         inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(),
1929                 any());
1930 
1931         // Change the legacy priority list that dun is higher than wifi.
1932         when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(
1933                 new int[] { TYPE_MOBILE_DUN, TYPE_WIFI });
1934         sendConfigurationChanged();
1935         mLooper.dispatchAll();
1936 
1937         // Make wifi as default network. Note: mobile also connected.
1938         wifi.fakeConnect();
1939         mLooper.dispatchAll();
1940         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1941         mLooper.dispatchAll();
1942         // BUG: dun has higher priority than wifi but tethering don't file dun request because
1943         // current upstream is wifi.
1944         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(false);
1945         inOrder.verify(mCm, never()).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(),
1946                 any());
1947 
1948         verifyDisableTryCellWhenTetheringStop(inOrder);
1949     }
1950 
setupDunUpstreamTest(final boolean automatic, InOrder inOrder)1951     private NetworkCallback setupDunUpstreamTest(final boolean automatic, InOrder inOrder) {
1952         when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(automatic);
1953         when(mTelephonyManager.isTetheringApnRequired()).thenReturn(true);
1954         sendConfigurationChanged();
1955         mLooper.dispatchAll();
1956 
1957         // Start USB tethering with no current upstream.
1958         prepareUsbTethering();
1959         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
1960         inOrder.verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks();
1961         inOrder.verify(mUpstreamNetworkMonitor).setTryCell(true);
1962         ArgumentCaptor<NetworkCallback> captor = ArgumentCaptor.forClass(NetworkCallback.class);
1963         inOrder.verify(mCm).requestNetwork(any(), eq(0), eq(TYPE_MOBILE_DUN), any(),
1964                 captor.capture() /* DUN network callback */);
1965 
1966         return captor.getValue();
1967     }
1968 
chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder, TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun)1969     private void chooseDunUpstreamTestCommon(final boolean automatic, InOrder inOrder,
1970             TestNetworkAgent mobile, TestNetworkAgent wifi, TestNetworkAgent dun)
1971             throws Exception {
1972         final NetworkCallback dunNetworkCallback = setupDunUpstreamTest(automatic, inOrder);
1973 
1974         // Pretend cellular connected and expect the upstream to be not set.
1975         mobile.fakeConnect();
1976         mCm.makeDefaultNetwork(mobile, BROADCAST_FIRST);
1977         mLooper.dispatchAll();
1978         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1979 
1980         // Pretend dun connected and expect choose dun as upstream.
1981         final Runnable doDispatchAll = () -> mLooper.dispatchAll();
1982         dun.fakeConnect(BROADCAST_FIRST, doDispatchAll);
1983         mLooper.dispatchAll();
1984         mTetheringEventCallback.expectUpstreamChanged(dun.networkId);
1985 
1986         // When wifi connected, unregister dun request and choose wifi as upstream.
1987         wifi.fakeConnect();
1988         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
1989         mLooper.dispatchAll();
1990         verifyWifiUpstreamAndUnregisterDunCallback(inOrder, wifi, dunNetworkCallback);
1991         dun.fakeDisconnect(BROADCAST_FIRST, doDispatchAll);
1992         mLooper.dispatchAll();
1993         mTetheringEventCallback.assertNoUpstreamChangeCallback();
1994     }
1995 
runNcmTethering()1996     private void runNcmTethering() {
1997         prepareNcmTethering();
1998         sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION);
1999     }
2000 
2001     @Test
workingNcmTethering()2002     public void workingNcmTethering() throws Exception {
2003         initTetheringOnTestThread();
2004         runNcmTethering();
2005 
2006         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
2007                 any(), any());
2008     }
2009 
2010     @Test
workingNcmTethering_LegacyDhcp()2011     public void workingNcmTethering_LegacyDhcp() throws Exception {
2012         initTetheringOnTestThread();
2013         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
2014                 true);
2015         sendConfigurationChanged();
2016         runNcmTethering();
2017 
2018         verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any());
2019     }
2020 
2021     @Test
workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged()2022     public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception {
2023         workingLocalOnlyHotspotEnrichedApBroadcast(true);
2024     }
2025 
2026     @Test
workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged()2027     public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception {
2028         workingLocalOnlyHotspotEnrichedApBroadcast(false);
2029     }
2030 
2031     @Test
failingWifiTetheringLegacyApBroadcast()2032     public void failingWifiTetheringLegacyApBroadcast() throws Exception {
2033         initTetheringOnTestThread();
2034 
2035         // Emulate pressing the WiFi tethering button.
2036         mTethering.startTethering(createTetheringRequest(TETHERING_WIFI), TEST_CALLER_PKG, null);
2037         mLooper.dispatchAll();
2038         verifyWifiTetheringRequested();
2039         verifyNoMoreInteractions(mNetd);
2040 
2041         // Emulate externally-visible WifiManager effects, causing the
2042         // per-interface state machine to start up, and telling us that
2043         // tethering mode is to be started.
2044         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
2045         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
2046         mLooper.dispatchAll();
2047 
2048         if (!SdkLevel.isAtLeastB()) {
2049             // There is 1 IpServer state change event: STATE_AVAILABLE from interfaceStatusChanged
2050             verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE);
2051             verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
2052             verify(mWifiManager).updateInterfaceIpState(
2053                     TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
2054         } else {
2055             // Starting in B, ignore the interfaceStatusChanged
2056             verify(mNotificationUpdater, never()).onDownstreamChanged(DOWNSTREAM_NONE);
2057             verify(mWifiManager, never()).updateInterfaceIpState(
2058                     TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
2059         }
2060         verifyNoMoreInteractions(mNetd);
2061         verifyNoMoreInteractions(mWifiManager);
2062     }
2063 
2064     // TODO: Test with and without interfaceStatusChanged().
2065     @Test
workingWifiTetheringEnrichedApBroadcast()2066     public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
2067         // B+ uses SoftApCallback instead of WIFI_AP_STATE_CHANGED for tethered hotspot.
2068         mTetheringWithSoftApConfigEnabled = false;
2069         initTetheringOnTestThread();
2070 
2071         // Emulate pressing the WiFi tethering button.
2072         mTethering.startTethering(createTetheringRequest(TETHERING_WIFI), TEST_CALLER_PKG,
2073                 null);
2074         mLooper.dispatchAll();
2075         verifyWifiTetheringRequested();
2076         verifyNoMoreInteractions(mNetd);
2077 
2078         // Emulate externally-visible WifiManager effects, causing the
2079         // per-interface state machine to start up, and telling us that
2080         // tethering mode is to be started.
2081         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
2082         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
2083 
2084         verifyStartHotspot();
2085         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
2086         // In tethering mode, in the default configuration, an explicit request
2087         // for a mobile network is also made.
2088         verify(mUpstreamNetworkMonitor, times(1)).setTryCell(true);
2089 
2090         /////
2091         // We do not currently emulate any upstream being found.
2092         //
2093         // This is why there are no calls to verify mNetd.tetherAddForward() or
2094         // mNetd.ipfwdAddInterfaceForward().
2095         /////
2096 
2097         // Emulate pressing the WiFi tethering button.
2098         mTethering.stopTethering(TETHERING_WIFI);
2099         mLooper.dispatchAll();
2100         verify(mWifiManager, times(1)).stopSoftAp();
2101         verifyNoMoreInteractions(mWifiManager);
2102         verifyNoMoreInteractions(mNetd);
2103 
2104         // Emulate externally-visible WifiManager effects, when tethering mode
2105         // is being torn down.
2106         sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
2107         mTethering.interfaceRemoved(TEST_WLAN_IFNAME);
2108         mLooper.dispatchAll();
2109 
2110         verifyStopHotpot(false /* isLocalOnly */);
2111     }
2112 
2113     @Test
startWifiTetheringWithSoftApConfigurationSuccess()2114     public void startWifiTetheringWithSoftApConfigurationSuccess() throws Exception {
2115         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2116         initTetheringOnTestThread();
2117 
2118         // Emulate pressing the WiFi tethering button.
2119         TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
2120                 .setSoftApConfiguration(new SoftApConfiguration.Builder()
2121                         .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8)))
2122                         .build())
2123                 .build();
2124         IIntResultListener startResultListener = mock(IIntResultListener.class);
2125         mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener);
2126         mLooper.dispatchAll();
2127         verifyNoMoreInteractions(mNetd);
2128         verify(startResultListener, never()).onResult(anyInt());
2129         // Emulate Wifi iface enabled
2130         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
2131 
2132         verifyStartHotspot();
2133         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
2134         verify(startResultListener).onResult(TETHER_ERROR_NO_ERROR);
2135     }
2136 
2137     @Test
startWifiTetheringWithSoftApConfigurationFailure()2138     public void startWifiTetheringWithSoftApConfigurationFailure() throws Exception {
2139         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2140         initTetheringOnTestThread();
2141 
2142         // Emulate pressing the WiFi tethering button.
2143         TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
2144                 .setSoftApConfiguration(new SoftApConfiguration.Builder()
2145                         .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8)))
2146                         .build())
2147                 .build();
2148         IIntResultListener startResultListener = mock(IIntResultListener.class);
2149         mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener);
2150         mLooper.dispatchAll();
2151         verify(startResultListener, never()).onResult(anyInt());
2152         // Emulate Wifi iface failure
2153         sendStartTetheringSoftApCallback(WIFI_AP_STATE_FAILED, request, TEST_WLAN_IFNAME);
2154 
2155         verify(startResultListener).onResult(TETHER_ERROR_INTERNAL_ERROR);
2156     }
2157 
2158     @Test
startWifiTetheringWithSoftApConfigurationRestartAfterStarting()2159     public void startWifiTetheringWithSoftApConfigurationRestartAfterStarting() throws Exception {
2160         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2161         initTetheringOnTestThread();
2162         TestTetheringEventCallback callback = new TestTetheringEventCallback();
2163         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
2164                 .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8)))
2165                 .build();
2166         final TetheringInterface wifiIface = new TetheringInterface(
2167                 TETHERING_WIFI, TEST_WLAN_IFNAME);
2168         final TetheringInterface wifiIfaceWithConfig = new TetheringInterface(
2169                 TETHERING_WIFI, TEST_WLAN_IFNAME, softApConfig);
2170 
2171         // 1. Register one callback before running any tethering.
2172         mTethering.registerTetheringEventCallback(callback);
2173         mLooper.dispatchAll();
2174         assertTetherStatesNotNullButEmpty(callback.pollTetherStatesChanged());
2175         // Emulate pressing the WiFi tethering button.
2176         TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
2177                 .setSoftApConfiguration(softApConfig)
2178                 .build();
2179         IIntResultListener startResultListener = mock(IIntResultListener.class);
2180         mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener);
2181         mLooper.dispatchAll();
2182 
2183         // Wifi success
2184         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
2185         verifyStartHotspot();
2186         TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
2187         assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
2188         tetherState = callback.pollTetherStatesChanged();
2189         assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIfaceWithConfig});
2190         verify(startResultListener).onResult(TETHER_ERROR_NO_ERROR);
2191 
2192         // Restart Wifi
2193         sendStartTetheringSoftApCallback(WIFI_AP_STATE_DISABLED, request, TEST_WLAN_IFNAME);
2194         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
2195 
2196         // Verify we go from TETHERED -> AVAILABLE -> TETHERED with the same config.
2197         tetherState = callback.pollTetherStatesChanged();
2198         assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
2199         tetherState = callback.pollTetherStatesChanged();
2200         assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIfaceWithConfig});
2201     }
2202 
2203     @Test
startWifiApBroadcastDoesNotStartIpServing()2204     public void startWifiApBroadcastDoesNotStartIpServing() throws Exception {
2205         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2206         initTetheringOnTestThread();
2207 
2208         // Call startTethering for wifi
2209         TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI)
2210                 .setSoftApConfiguration(new SoftApConfiguration.Builder()
2211                         .setWifiSsid(WifiSsid.fromBytes("SSID".getBytes(StandardCharsets.UTF_8)))
2212                         .build())
2213                 .build();
2214         IIntResultListener startResultListener = mock(IIntResultListener.class);
2215         mTethering.startTethering(request, TEST_CALLER_PKG, startResultListener);
2216         mLooper.dispatchAll();
2217 
2218         // WIFI_AP_STATE_CHANGED broadcast should be ignored since we should only be using
2219         // SoftApCallback for tethered AP.
2220         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
2221         sendWifiApStateChanged(WIFI_AP_STATE_DISABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
2222         verify(mNetd, never()).tetherStartWithConfiguration(any());
2223         verify(mNotificationUpdater, never()).onDownstreamChanged(DOWNSTREAM_NONE);
2224         verify(mWifiManager, never()).updateInterfaceIpState(
2225                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
2226         assertTrue(mTethering.getServingTetheringRequests().isEmpty());
2227     }
2228 
2229     // TODO: Test with and without interfaceStatusChanged().
2230     @Test
failureEnablingIpForwarding()2231     public void failureEnablingIpForwarding() throws Exception {
2232         initTetheringOnTestThread();
2233         doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
2234 
2235         // Emulate pressing the WiFi tethering button.
2236         TetheringRequest request = createTetheringRequest(TETHERING_WIFI);
2237         mTethering.startTethering(request, TEST_CALLER_PKG, null);
2238         mLooper.dispatchAll();
2239         verifyWifiTetheringRequested();
2240         verifyNoMoreInteractions(mNetd);
2241         verify(mTetheringMetrics).createBuilder(eq(TETHERING_WIFI), anyString());
2242 
2243         // Emulate externally-visible WifiManager effects, causing the
2244         // per-interface state machine to start up, and telling us that
2245         // tethering mode is to be started.
2246         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
2247         sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
2248 
2249         // We verify get/set called three times here: twice for setup and once during
2250         // teardown because all events happen over the course of the single
2251         // dispatchAll() above. Note that once the IpServer IPv4 address config
2252         // code is refactored the two calls during shutdown will revert to one.
2253         verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName)));
2254         verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME);
2255         if (isTetheringNetworkAgentFeatureEnabled()) {
2256             verify(mNetd, never()).networkAddInterface(anyInt(), anyString());
2257             verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString());
2258         } else {
2259             verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
2260             verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME),
2261                     anyString(), anyString());
2262         }
2263         verify(mWifiManager).updateInterfaceIpState(
2264                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
2265         verify(mWifiManager).updateInterfaceIpState(
2266                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
2267         // There are 3 IpServer state change event:
2268         //         STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE.
2269         verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
2270         verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI));
2271         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
2272         // This is called, but will throw.
2273         verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
2274         // This never gets called because of the exception thrown above.
2275         verify(mNetd, times(0)).tetherStartWithConfiguration(any());
2276         // When the main state machine transitions to an error state it tells
2277         // downstream interfaces, which causes us to tell Wi-Fi about the error
2278         // so it can take down AP mode.
2279         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
2280         verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME);
2281         if (isTetheringNetworkAgentFeatureEnabled()) {
2282             verify(mNetd, never()).networkRemoveInterface(anyInt(), anyString());
2283         } else {
2284             verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME);
2285         }
2286         verify(mWifiManager).updateInterfaceIpState(
2287                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
2288 
2289         verify(mTetheringMetrics, times(0)).maybeUpdateUpstreamType(any());
2290         verify(mTetheringMetrics, times(1)).updateErrorCode(eq(TETHERING_WIFI),
2291                 eq(TETHER_ERROR_INTERNAL_ERROR));
2292         verify(mTetheringMetrics, times(1)).sendReport(eq(TETHERING_WIFI));
2293 
2294         verifyNoMoreInteractions(mWifiManager);
2295         verifyNoMoreInteractions(mNetd);
2296     }
2297 
makeUserRestrictionActionListener( final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow)2298     private UserRestrictionActionListener makeUserRestrictionActionListener(
2299             final Tethering tethering, final boolean currentDisallow, final boolean nextDisallow) {
2300         final Bundle newRestrictions = new Bundle();
2301         newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
2302         when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
2303 
2304         final UserRestrictionActionListener ural =
2305                 new UserRestrictionActionListener(mUserManager, tethering, mNotificationUpdater);
2306         ural.mDisallowTethering = currentDisallow;
2307         return ural;
2308     }
2309 
runUserRestrictionsChange( boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, int expectedInteractionsWithShowNotification)2310     private void runUserRestrictionsChange(
2311             boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive,
2312             int expectedInteractionsWithShowNotification) throws  Exception {
2313         final Tethering mockTethering = mock(Tethering.class);
2314         when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive);
2315 
2316         final UserRestrictionActionListener ural =
2317                 makeUserRestrictionActionListener(mockTethering, currentDisallow, nextDisallow);
2318         ural.onUserRestrictionsChanged();
2319 
2320         verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification))
2321                 .notifyTetheringDisabledByRestriction();
2322         verify(mockTethering, times(expectedInteractionsWithShowNotification)).stopAllTethering();
2323     }
2324 
2325     @Test
testDisallowTetheringWhenTetheringIsNotActive()2326     public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception {
2327         final boolean isTetheringActive = false;
2328         final boolean currDisallow = false;
2329         final boolean nextDisallow = true;
2330         final int expectedInteractionsWithShowNotification = 0;
2331 
2332         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
2333                 expectedInteractionsWithShowNotification);
2334     }
2335 
2336     @Test
testDisallowTetheringWhenTetheringIsActive()2337     public void testDisallowTetheringWhenTetheringIsActive() throws Exception {
2338         final boolean isTetheringActive = true;
2339         final boolean currDisallow = false;
2340         final boolean nextDisallow = true;
2341         final int expectedInteractionsWithShowNotification = 1;
2342 
2343         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
2344                 expectedInteractionsWithShowNotification);
2345     }
2346 
2347     @Test
testAllowTetheringWhenTetheringIsNotActive()2348     public void testAllowTetheringWhenTetheringIsNotActive() throws Exception {
2349         final boolean isTetheringActive = false;
2350         final boolean currDisallow = true;
2351         final boolean nextDisallow = false;
2352         final int expectedInteractionsWithShowNotification = 0;
2353 
2354         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
2355                 expectedInteractionsWithShowNotification);
2356     }
2357 
2358     @Test
testAllowTetheringWhenTetheringIsActive()2359     public void testAllowTetheringWhenTetheringIsActive() throws Exception {
2360         final boolean isTetheringActive = true;
2361         final boolean currDisallow = true;
2362         final boolean nextDisallow = false;
2363         final int expectedInteractionsWithShowNotification = 0;
2364 
2365         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
2366                 expectedInteractionsWithShowNotification);
2367     }
2368 
2369     @Test
testDisallowTetheringUnchanged()2370     public void testDisallowTetheringUnchanged() throws Exception {
2371         final boolean isTetheringActive = true;
2372         final int expectedInteractionsWithShowNotification = 0;
2373         boolean currDisallow = true;
2374         boolean nextDisallow = true;
2375 
2376         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
2377                 expectedInteractionsWithShowNotification);
2378 
2379         currDisallow = false;
2380         nextDisallow = false;
2381 
2382         runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
2383                 expectedInteractionsWithShowNotification);
2384     }
2385 
2386     @Test
testUntetherUsbWhenRestrictionIsOn()2387     public void testUntetherUsbWhenRestrictionIsOn() throws Exception {
2388         initTetheringOnTestThread();
2389         // Start usb tethering and check that usb interface is tethered.
2390         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
2391         runUsbTethering(upstreamState);
2392         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
2393         assertTrue(mTethering.isTetheringActive());
2394         assertEquals(0, mTethering.getPendingTetheringRequests().size());
2395 
2396         final Tethering.UserRestrictionActionListener ural = makeUserRestrictionActionListener(
2397                 mTethering, false /* currentDisallow */, true /* nextDisallow */);
2398 
2399         ural.onUserRestrictionsChanged();
2400         mLooper.dispatchAll();
2401 
2402         // Verify that restriction notification has showed to user.
2403         verify(mNotificationUpdater, times(1)).notifyTetheringDisabledByRestriction();
2404         // Verify that usb tethering has been disabled.
2405         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
2406     }
2407 
2408     private class TestTetheringEventCallback extends ITetheringEventCallback.Stub {
2409         private final ArrayList<Network> mActualUpstreams = new ArrayList<>();
2410         private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs =
2411                 new ArrayList<>();
2412         private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>();
2413         private final ArrayList<Integer> mOffloadStatus = new ArrayList<>();
2414         private final ArrayList<List<TetheredClient>> mTetheredClients = new ArrayList<>();
2415         private final ArrayList<Long> mSupportedBitmaps = new ArrayList<>();
2416 
2417         // This function will remove the recorded callbacks, so it must be called once for
2418         // each callback. If this is called after multiple callback, the order matters.
2419         // onCallbackCreated counts as the first call to expectUpstreamChanged with
2420         // @see onCallbackCreated.
expectUpstreamChanged(Network... networks)2421         public void expectUpstreamChanged(Network... networks) {
2422             if (networks == null) {
2423                 assertNoUpstreamChangeCallback();
2424                 return;
2425             }
2426 
2427             final ArrayList<Network> expectedUpstreams =
2428                     new ArrayList<Network>(Arrays.asList(networks));
2429             for (Network upstream : expectedUpstreams) {
2430                 // throws OOB if no expectations
2431                 assertEquals(upstream, mActualUpstreams.remove(0));
2432             }
2433             assertNoUpstreamChangeCallback();
2434         }
2435 
2436         // This function will remove the recorded callbacks, so it must be called once
2437         // for each callback. If this is called after multiple callback, the order matters.
2438         // onCallbackCreated counts as the first call to onConfigurationChanged with
2439         // @see onCallbackCreated.
expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs)2440         public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) {
2441             final ArrayList<TetheringConfigurationParcel> expectedTetherConfig =
2442                     new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs));
2443             for (TetheringConfigurationParcel config : expectedTetherConfig) {
2444                 // throws OOB if no expectations
2445                 final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0);
2446                 assertTetherConfigParcelEqual(config, actualConfig);
2447             }
2448             assertNoConfigChangeCallback();
2449         }
2450 
expectOffloadStatusChanged(final int expectedStatus)2451         public void expectOffloadStatusChanged(final int expectedStatus) {
2452             assertOffloadStatusChangedCallback();
2453             assertEquals(Integer.valueOf(expectedStatus), mOffloadStatus.remove(0));
2454         }
2455 
pollTetherStatesChanged()2456         public TetherStatesParcel pollTetherStatesChanged() {
2457             assertStateChangeCallback();
2458             return mTetherStates.remove(0);
2459         }
2460 
expectTetheredClientChanged(List<TetheredClient> leases)2461         public void expectTetheredClientChanged(List<TetheredClient> leases) {
2462             assertFalse(mTetheredClients.isEmpty());
2463             final List<TetheredClient> result = mTetheredClients.remove(0);
2464             assertEquals(leases.size(), result.size());
2465             assertTrue(leases.containsAll(result));
2466         }
2467 
expectSupportedTetheringTypes(Set<Integer> expectedTypes)2468         public void expectSupportedTetheringTypes(Set<Integer> expectedTypes) {
2469             assertEquals(expectedTypes, TetheringManager.unpackBits(mSupportedBitmaps.remove(0)));
2470         }
2471 
2472         @Override
onUpstreamChanged(Network network)2473         public void onUpstreamChanged(Network network) {
2474             mActualUpstreams.add(network);
2475         }
2476 
2477         @Override
onConfigurationChanged(TetheringConfigurationParcel config)2478         public void onConfigurationChanged(TetheringConfigurationParcel config) {
2479             mTetheringConfigs.add(config);
2480         }
2481 
2482         @Override
onTetherStatesChanged(TetherStatesParcel states)2483         public void onTetherStatesChanged(TetherStatesParcel states) {
2484             mTetherStates.add(states);
2485         }
2486 
2487         @Override
onTetherClientsChanged(List<TetheredClient> clients)2488         public void onTetherClientsChanged(List<TetheredClient> clients) {
2489             mTetheredClients.add(clients);
2490         }
2491 
2492         @Override
onOffloadStatusChanged(final int status)2493         public void onOffloadStatusChanged(final int status) {
2494             mOffloadStatus.add(status);
2495         }
2496 
2497         @Override
onCallbackStarted(TetheringCallbackStartedParcel parcel)2498         public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
2499             mActualUpstreams.add(parcel.upstreamNetwork);
2500             mTetheringConfigs.add(parcel.config);
2501             mTetherStates.add(parcel.states);
2502             mOffloadStatus.add(parcel.offloadStatus);
2503             mTetheredClients.add(parcel.tetheredClients);
2504             mSupportedBitmaps.add(parcel.supportedTypes);
2505         }
2506 
2507         @Override
onCallbackStopped(int errorCode)2508         public void onCallbackStopped(int errorCode) { }
2509 
2510         @Override
onSupportedTetheringTypes(long supportedBitmap)2511         public void onSupportedTetheringTypes(long supportedBitmap) {
2512             mSupportedBitmaps.add(supportedBitmap);
2513         }
2514 
assertNoUpstreamChangeCallback()2515         public void assertNoUpstreamChangeCallback() {
2516             assertTrue(mActualUpstreams.isEmpty());
2517         }
2518 
assertNoConfigChangeCallback()2519         public void assertNoConfigChangeCallback() {
2520             assertTrue(mTetheringConfigs.isEmpty());
2521         }
2522 
assertNoStateChangeCallback()2523         public void assertNoStateChangeCallback() {
2524             assertTrue(mTetherStates.isEmpty());
2525         }
2526 
assertStateChangeCallback()2527         public void assertStateChangeCallback() {
2528             assertFalse(mTetherStates.isEmpty());
2529         }
2530 
assertOffloadStatusChangedCallback()2531         public void assertOffloadStatusChangedCallback() {
2532             assertFalse(mOffloadStatus.isEmpty());
2533         }
2534 
assertNoCallback()2535         public void assertNoCallback() {
2536             assertNoUpstreamChangeCallback();
2537             assertNoConfigChangeCallback();
2538             assertNoStateChangeCallback();
2539             assertTrue(mTetheredClients.isEmpty());
2540         }
2541 
assertTetherConfigParcelEqual(@onNull TetheringConfigurationParcel actual, @NonNull TetheringConfigurationParcel expect)2542         private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
2543                 @NonNull TetheringConfigurationParcel expect) {
2544             assertArrayEquals(expect.tetherableUsbRegexs, actual.tetherableUsbRegexs);
2545             assertArrayEquals(expect.tetherableWifiRegexs, actual.tetherableWifiRegexs);
2546             assertArrayEquals(expect.tetherableBluetoothRegexs, actual.tetherableBluetoothRegexs);
2547             assertArrayEquals(expect.legacyDhcpRanges, actual.legacyDhcpRanges);
2548             assertArrayEquals(expect.provisioningApp, actual.provisioningApp);
2549             assertEquals(expect.provisioningAppNoUi, actual.provisioningAppNoUi);
2550         }
2551     }
2552 
assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel)2553     private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) {
2554         assertFalse(parcel == null);
2555         assertEquals(0, parcel.availableList.length);
2556         assertEquals(0, parcel.tetheredList.length);
2557         assertEquals(0, parcel.localOnlyList.length);
2558         assertEquals(0, parcel.erroredIfaceList.length);
2559         assertEquals(0, parcel.lastErrorList.length);
2560         MiscAsserts.assertFieldCountEquals(5, TetherStatesParcel.class);
2561     }
2562 
2563     @Test
testRegisterTetheringEventCallback()2564     public void testRegisterTetheringEventCallback() throws Exception {
2565         initTetheringOnTestThread();
2566         TestTetheringEventCallback callback = new TestTetheringEventCallback();
2567         TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
2568         final TetheringInterface wifiIface = new TetheringInterface(
2569                 TETHERING_WIFI, TEST_WLAN_IFNAME);
2570 
2571         // 1. Register one callback before running any tethering.
2572         mTethering.registerTetheringEventCallback(callback);
2573         mLooper.dispatchAll();
2574         callback.expectTetheredClientChanged(Collections.emptyList());
2575         callback.expectUpstreamChanged(NULL_NETWORK);
2576         callback.expectConfigurationChanged(
2577                 mTethering.getTetheringConfiguration().toStableParcelable());
2578         TetherStatesParcel tetherState = callback.pollTetherStatesChanged();
2579         assertTetherStatesNotNullButEmpty(tetherState);
2580         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
2581         // 2. Enable wifi tethering.
2582         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
2583         initTetheringUpstream(upstreamState);
2584 
2585         TetheringRequest request = createTetheringRequest(TETHERING_WIFI);
2586         mTethering.startTethering(request, TEST_CALLER_PKG,
2587                 null);
2588         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
2589         mLooper.dispatchAll();
2590         if (SdkLevel.isAtLeastB()) {
2591             // Starting in B, ignore the interfaceStatusChanged
2592             callback.assertNoStateChangeCallback();
2593         }
2594         sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
2595         mLooper.dispatchAll();
2596         tetherState = callback.pollTetherStatesChanged();
2597         assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
2598         tetherState = callback.pollTetherStatesChanged();
2599         assertArrayEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface});
2600         callback.expectUpstreamChanged(upstreamState.network);
2601         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
2602 
2603         // 3. Register second callback.
2604         mTethering.registerTetheringEventCallback(callback2);
2605         mLooper.dispatchAll();
2606         callback2.expectTetheredClientChanged(Collections.emptyList());
2607         callback2.expectUpstreamChanged(upstreamState.network);
2608         callback2.expectConfigurationChanged(
2609                 mTethering.getTetheringConfiguration().toStableParcelable());
2610         tetherState = callback2.pollTetherStatesChanged();
2611         assertEquals(tetherState.tetheredList, new TetheringInterface[] {wifiIface});
2612         callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
2613 
2614         // 4. Unregister first callback and disable wifi tethering
2615         mTethering.unregisterTetheringEventCallback(callback);
2616         mLooper.dispatchAll();
2617         mTethering.stopTethering(TETHERING_WIFI);
2618         sendWifiApStateChanged(WIFI_AP_STATE_DISABLED);
2619         if (isAtLeastT()) {
2620             // After T, tethering doesn't support WIFI_AP_STATE_DISABLED with null interface name.
2621             callback2.assertNoStateChangeCallback();
2622             sendSoftApEvent(WIFI_AP_STATE_DISABLED, request, TEST_WLAN_IFNAME);
2623         }
2624         tetherState = callback2.pollTetherStatesChanged();
2625         assertArrayEquals(tetherState.availableList, new TetheringInterface[] {wifiIface});
2626         mLooper.dispatchAll();
2627         callback2.expectUpstreamChanged(NULL_NETWORK);
2628         callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
2629         callback.assertNoCallback();
2630     }
2631 
2632     @Test
testSoftApConfigInTetheringEventCallback()2633     public void testSoftApConfigInTetheringEventCallback() throws Exception {
2634         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2635         when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS))
2636                 .thenReturn(PERMISSION_DENIED);
2637         when(mContext.checkCallingOrSelfPermission(NETWORK_STACK))
2638                 .thenReturn(PERMISSION_DENIED);
2639         when(mContext.checkCallingOrSelfPermission(PERMISSION_MAINLINE_NETWORK_STACK))
2640                 .thenReturn(PERMISSION_DENIED);
2641         initTetheringOnTestThread();
2642         TestTetheringEventCallback callback = new TestTetheringEventCallback();
2643         TestTetheringEventCallback differentCallback = new TestTetheringEventCallback();
2644         TestTetheringEventCallback settingsCallback = new TestTetheringEventCallback();
2645         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid(
2646                 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build();
2647         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
2648                 .setSoftApConfiguration(softApConfig).build();
2649         tetheringRequest.setUid(TEST_CALLER_UID);
2650         final TetheringInterface wifiIfaceWithoutConfig = new TetheringInterface(
2651                 TETHERING_WIFI, TEST_WLAN_IFNAME, null);
2652         final TetheringInterface wifiIfaceWithConfig = new TetheringInterface(
2653                 TETHERING_WIFI, TEST_WLAN_IFNAME, softApConfig);
2654 
2655         // Register callback before running any tethering.
2656         mTethering.registerTetheringEventCallback(callback);
2657         mLooper.dispatchAll();
2658         callback.expectTetheredClientChanged(Collections.emptyList());
2659         callback.expectUpstreamChanged(NULL_NETWORK);
2660         callback.expectConfigurationChanged(
2661                 mTethering.getTetheringConfiguration().toStableParcelable());
2662         // Register callback with different UID
2663         mBinderCallingUid = TEST_CALLER_UID + 1;
2664         mTethering.registerTetheringEventCallback(differentCallback);
2665         mLooper.dispatchAll();
2666         differentCallback.expectTetheredClientChanged(Collections.emptyList());
2667         differentCallback.expectUpstreamChanged(NULL_NETWORK);
2668         differentCallback.expectConfigurationChanged(
2669                 mTethering.getTetheringConfiguration().toStableParcelable());
2670         // Register Settings callback
2671         when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS))
2672                 .thenReturn(PERMISSION_GRANTED);
2673         mTethering.registerTetheringEventCallback(settingsCallback);
2674         mLooper.dispatchAll();
2675         settingsCallback.expectTetheredClientChanged(Collections.emptyList());
2676         settingsCallback.expectUpstreamChanged(NULL_NETWORK);
2677         settingsCallback.expectConfigurationChanged(
2678                 mTethering.getTetheringConfiguration().toStableParcelable());
2679 
2680         assertTetherStatesNotNullButEmpty(callback.pollTetherStatesChanged());
2681         assertTetherStatesNotNullButEmpty(differentCallback.pollTetherStatesChanged());
2682         assertTetherStatesNotNullButEmpty(settingsCallback.pollTetherStatesChanged());
2683         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
2684         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
2685         initTetheringUpstream(upstreamState);
2686 
2687         // Enable wifi tethering
2688         mBinderCallingUid = TEST_CALLER_UID;
2689         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, null);
2690         mLooper.dispatchAll();
2691         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
2692         mLooper.dispatchAll();
2693         // Netd "up" event should not trigger a state change callback in B+.
2694         callback.assertNoStateChangeCallback();
2695         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest,
2696                 TEST_WLAN_IFNAME);
2697         // Verify we see  Available -> Tethered states
2698         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2699                 callback.pollTetherStatesChanged().availableList);
2700         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2701                 differentCallback.pollTetherStatesChanged().availableList);
2702         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2703                 settingsCallback.pollTetherStatesChanged().availableList);
2704         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithConfig},
2705                 callback.pollTetherStatesChanged().tetheredList);
2706         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2707                 differentCallback.pollTetherStatesChanged().tetheredList);
2708         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithConfig},
2709                 settingsCallback.pollTetherStatesChanged().tetheredList);
2710         callback.expectUpstreamChanged(upstreamState.network);
2711         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
2712 
2713         // Disable wifi tethering
2714         mTethering.stopTethering(TETHERING_WIFI);
2715         mLooper.dispatchAll();
2716         sendStartTetheringSoftApCallback(WIFI_AP_STATE_DISABLED, tetheringRequest,
2717                 TEST_WLAN_IFNAME);
2718         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2719                 callback.pollTetherStatesChanged().availableList);
2720         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2721                 differentCallback.pollTetherStatesChanged().availableList);
2722         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2723                 settingsCallback.pollTetherStatesChanged().availableList);
2724         mLooper.dispatchAll();
2725         callback.expectUpstreamChanged(NULL_NETWORK);
2726         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
2727         callback.assertNoCallback();
2728     }
2729 
2730     @Test
testFuzzyMatchedWifiCannotBeAdded()2731     public void testFuzzyMatchedWifiCannotBeAdded() throws Exception {
2732         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2733         initTetheringOnTestThread();
2734         TestTetheringEventCallback callback = new TestTetheringEventCallback();
2735         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid(
2736                 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build();
2737         final TetheringInterface wifiIfaceWithoutConfig = new TetheringInterface(
2738                 TETHERING_WIFI, TEST_WLAN_IFNAME, null);
2739         final TetheringInterface wifiIfaceWithConfig = new TetheringInterface(
2740                 TETHERING_WIFI, TEST_WLAN_IFNAME, softApConfig);
2741 
2742         // Register callback before running any tethering.
2743         mTethering.registerTetheringEventCallback(callback);
2744         mLooper.dispatchAll();
2745         callback.expectTetheredClientChanged(Collections.emptyList());
2746         callback.expectUpstreamChanged(NULL_NETWORK);
2747         callback.expectConfigurationChanged(
2748                 mTethering.getTetheringConfiguration().toStableParcelable());
2749         assertTetherStatesNotNullButEmpty(callback.pollTetherStatesChanged());
2750         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
2751         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
2752         initTetheringUpstream(upstreamState);
2753 
2754         // Start wifi tethering but don't trigger the link layer event yet.
2755         mBinderCallingUid = TEST_CALLER_UID;
2756         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
2757                 .setSoftApConfiguration(softApConfig).build();
2758         tetheringRequest.setUid(TEST_CALLER_UID);
2759         ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR);
2760         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener);
2761         mLooper.dispatchAll();
2762         successListener.assertDoesNotHaveResult();
2763 
2764         // Try starting wifi tethering with various fuzzy-matching requests and verify we get
2765         // TETHER_ERROR_DUPLICATE_REQUEST.
2766 
2767         // Different static IP addresses
2768         final TetheringRequest differentIpAddr = new TetheringRequest.Builder(TETHERING_WIFI)
2769                 .setSoftApConfiguration(softApConfig)
2770                 .setStaticIpv4Addresses(new LinkAddress("192.168.0.123/24"),
2771                         new LinkAddress("192.168.0.42/24"))
2772                 .build();
2773         differentIpAddr.setUid(TEST_CALLER_UID);
2774         ResultListener differentIpAddrListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2775         mTethering.startTethering(differentIpAddr, TEST_CALLER_PKG, differentIpAddrListener);
2776         mLooper.dispatchAll();
2777         verifyWifiTetheringRequested();
2778         differentIpAddrListener.assertHasResult();
2779 
2780         // Different UID
2781         final TetheringRequest differentUid = new TetheringRequest.Builder(TETHERING_WIFI)
2782                 .setSoftApConfiguration(softApConfig).build();
2783         differentUid.setUid(TEST_CALLER_UID + 1);
2784         ResultListener differentUidListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2785         mTethering.startTethering(differentUid, TEST_CALLER_PKG, differentUidListener);
2786         mLooper.dispatchAll();
2787         differentUidListener.assertHasResult();
2788         verifyWifiTetheringRequested();
2789 
2790         // Mock the link layer event to start IP serving and verify
2791         // 1) The original request's result listener is called.
2792         // 2) We still get TETHER_ERROR_DUPLICATE_REQUEST for new requests.
2793         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2794         successListener.assertHasResult();
2795         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithoutConfig},
2796                 callback.pollTetherStatesChanged().availableList);
2797         assertArrayEquals(new TetheringInterface[] {wifiIfaceWithConfig},
2798                 callback.pollTetherStatesChanged().tetheredList);
2799         callback.expectUpstreamChanged(upstreamState.network);
2800         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED);
2801         differentIpAddrListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2802         differentUidListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2803         mTethering.startTethering(differentIpAddr, TEST_CALLER_PKG, differentIpAddrListener);
2804         mTethering.startTethering(differentUid, TEST_CALLER_PKG, differentUidListener);
2805         mLooper.dispatchAll();
2806         differentIpAddrListener.assertHasResult();
2807         differentUidListener.assertHasResult();
2808         verify(mWifiManager, times(1)).startTetheredHotspot(any(), any(), any());
2809         verify(mWifiManager, never()).stopSoftAp();
2810     }
2811 
2812     @Test
testFuzzyMatchedWifiCanBeAddedAfterIpServerStopped()2813     public void testFuzzyMatchedWifiCanBeAddedAfterIpServerStopped() throws Exception {
2814         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2815         initTetheringOnTestThread();
2816 
2817         // Start wifi tethering and mock the ap state change.
2818         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid(
2819                 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build();
2820         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
2821                 .setSoftApConfiguration(softApConfig).build();
2822         ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR);
2823         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener);
2824         mLooper.dispatchAll();
2825         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2826         successListener.assertHasResult();
2827 
2828         // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST
2829         ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2830         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener);
2831         mLooper.dispatchAll();
2832         failureListener.assertHasResult();
2833 
2834         // Trigger Netd callback to stop the IpServer
2835         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, false);
2836 
2837         // We should be able to request the same Wifi again
2838         ResultListener successListener2 = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2839         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2);
2840         mLooper.dispatchAll();
2841         successListener2.assertHasResult();
2842     }
2843 
2844     @Test
testFuzzyMatchedWifiCanBeAddedAfterIpServerUnwanted()2845     public void testFuzzyMatchedWifiCanBeAddedAfterIpServerUnwanted() throws Exception {
2846         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2847         initTetheringOnTestThread();
2848 
2849         // Start wifi tethering and mock the ap state change.
2850         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid(
2851                 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build();
2852         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
2853                 .setSoftApConfiguration(softApConfig).build();
2854         ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR);
2855         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener);
2856         mLooper.dispatchAll();
2857         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2858         successListener.assertHasResult();
2859         // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST
2860         ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2861         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener);
2862         mLooper.dispatchAll();
2863         failureListener.assertHasResult();
2864 
2865         // Trigger wifi ap state change to tell IpServer it's unwanted.
2866         sendStartTetheringSoftApCallback(WIFI_AP_STATE_DISABLED, tetheringRequest,
2867                 TEST_WLAN_IFNAME);
2868 
2869         // We should be able to request the same Wifi again
2870         ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR);
2871         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2);
2872         mLooper.dispatchAll();
2873         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest,
2874                 TEST_WLAN_IFNAME);
2875         successListener2.assertHasResult();
2876     }
2877 
2878     @Test
testFuzzyMatchedWifiCanBeAddedAfterIpServerError()2879     public void testFuzzyMatchedWifiCanBeAddedAfterIpServerError() throws Exception {
2880         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2881         initTetheringOnTestThread();
2882 
2883         // Set up the DHCP server to fail creation.
2884         mIpServerDependencies.setOnDhcpServerCreatedResult(STATUS_UNKNOWN_ERROR);
2885 
2886         // Start wifi tethering and mock the ap state change.
2887         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid(
2888                 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build();
2889         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
2890                 .setSoftApConfiguration(softApConfig).build();
2891         ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR);
2892         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener);
2893         mLooper.dispatchAll();
2894         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2895         successListener.assertHasResult();
2896 
2897         // We should be able to request the same Wifi again since the DHCP server transitioned the
2898         // IpServer back to InitialState.
2899         ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR);
2900         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2);
2901         mLooper.dispatchAll();
2902         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2903         successListener2.assertHasResult();
2904     }
2905 
2906     @Test
testFuzzyMatchedWifiCanBeAddedAfterStoppingPendingRequest()2907     public void testFuzzyMatchedWifiCanBeAddedAfterStoppingPendingRequest() throws Exception {
2908         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2909         initTetheringOnTestThread();
2910 
2911         // Start wifi tethering but keep the request pending by not sending the ap state change.
2912         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid(
2913                 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build();
2914         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
2915                 .setSoftApConfiguration(softApConfig).build();
2916         ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR);
2917         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener);
2918         mLooper.dispatchAll();
2919         ArgumentCaptor<SoftApCallback> callbackCaptor =
2920                 ArgumentCaptor.forClass(SoftApCallback.class);
2921         verify(mWifiManager, atLeastOnce()).startTetheredHotspot(any(TetheringRequest.class),
2922                 any(Executor.class), callbackCaptor.capture());
2923 
2924         // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST
2925         ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2926         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener);
2927         mLooper.dispatchAll();
2928         failureListener.assertHasResult();
2929 
2930         // Stop Wifi tethering.
2931         mTethering.stopTethering(TETHERING_WIFI);
2932 
2933         // We should be able to request the same Wifi again
2934         ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR);
2935         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2);
2936         mLooper.dispatchAll();
2937         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2938         successListener2.assertHasResult();
2939 
2940         // Mock the first request going up and then down from the stop request.
2941         SoftApState softApState = mock(SoftApState.class);
2942         when(softApState.getState()).thenReturn(WIFI_AP_STATE_ENABLED);
2943         when(softApState.getTetheringRequest()).thenReturn(tetheringRequest);
2944         when(softApState.getIface()).thenReturn(TEST_WLAN_IFNAME);
2945         callbackCaptor.getValue().onStateChanged(softApState);
2946         mLooper.dispatchAll();
2947         successListener.assertHasResult();
2948 
2949         // Mock the second request going up
2950         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2951         successListener2.assertHasResult();
2952     }
2953 
2954     @Test
testFuzzyMatchedWifiCanBeAddedAfterStoppingServingRequest()2955     public void testFuzzyMatchedWifiCanBeAddedAfterStoppingServingRequest() throws Exception {
2956         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2957         initTetheringOnTestThread();
2958 
2959         // Start wifi tethering and mock the ap state change.
2960         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder().setWifiSsid(
2961                 WifiSsid.fromBytes("SoftApConfig".getBytes(StandardCharsets.UTF_8))).build();
2962         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
2963                 .setSoftApConfiguration(softApConfig).build();
2964         ResultListener successListener = new ResultListener(TETHER_ERROR_NO_ERROR);
2965         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener);
2966         mLooper.dispatchAll();
2967         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2968         successListener.assertHasResult();
2969 
2970         // Starting wifi again will cause TETHER_ERROR_DUPLICATE_REQUEST
2971         ResultListener failureListener = new ResultListener(TETHER_ERROR_DUPLICATE_REQUEST);
2972         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, failureListener);
2973         mLooper.dispatchAll();
2974         failureListener.assertHasResult();
2975 
2976         // Stop Wifi tethering.
2977         mTethering.stopTethering(TETHERING_WIFI);
2978 
2979         // We should be able to request the same Wifi again
2980         ResultListener successListener2 = new ResultListener(TETHER_ERROR_NO_ERROR);
2981         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, successListener2);
2982         mLooper.dispatchAll();
2983         sendStartTetheringSoftApCallback(WIFI_AP_STATE_ENABLED, tetheringRequest, TEST_WLAN_IFNAME);
2984         successListener2.assertHasResult();
2985     }
2986 
2987     @Test
testStopTetheringWithMatchingRequest()2988     public void testStopTetheringWithMatchingRequest() throws Exception {
2989         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
2990         when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS)).thenReturn(PERMISSION_DENIED);
2991         initTetheringOnTestThread();
2992         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
2993         initTetheringUpstream(upstreamState);
2994 
2995         // Enable wifi tethering.
2996         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
2997                 .setSsid("SoftApConfig")
2998                 .build();
2999         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
3000                 .setSoftApConfiguration(softApConfig).build();
3001         tetheringRequest.setUid(TEST_CALLER_UID);
3002         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, null);
3003         mLooper.dispatchAll();
3004 
3005         // Stop tethering with non-matching config. Should fail with TETHER_ERROR_UNKNOWN_REQUEST.
3006         SoftApConfiguration softApConfig2 = new SoftApConfiguration.Builder()
3007                 .setSsid("SoftApConfig2")
3008                 .build();
3009         IIntResultListener differentConfigListener = mock(IIntResultListener.class);
3010         mTethering.stopTetheringRequest(new TetheringRequest.Builder(TETHERING_WIFI)
3011                 .setSoftApConfiguration(softApConfig2).build(), differentConfigListener);
3012         mLooper.dispatchAll();
3013         verify(differentConfigListener).onResult(eq(TETHER_ERROR_UNKNOWN_REQUEST));
3014         verify(mWifiManager, never()).stopSoftAp();
3015 
3016         // Stop tethering with non-matching UID. Should fail with TETHER_ERROR_UNKNOWN_REQUEST.
3017         final TetheringRequest nonMatchingUid = new TetheringRequest.Builder(TETHERING_WIFI)
3018                 .setSoftApConfiguration(softApConfig).build();
3019         IIntResultListener nonMatchingUidListener = mock(IIntResultListener.class);
3020         nonMatchingUid.setUid(TEST_CALLER_UID_2);
3021         mTethering.stopTetheringRequest(nonMatchingUid, nonMatchingUidListener);
3022         mLooper.dispatchAll();
3023         verify(nonMatchingUidListener).onResult(eq(TETHER_ERROR_UNKNOWN_REQUEST));
3024         verify(mWifiManager, never()).stopSoftAp();
3025 
3026         // Stop tethering with matching request. Should succeed now.
3027         IIntResultListener matchingListener = mock(IIntResultListener.class);
3028         mTethering.stopTetheringRequest(tetheringRequest, matchingListener);
3029         mLooper.dispatchAll();
3030         verify(matchingListener).onResult(eq(TETHER_ERROR_NO_ERROR));
3031         verify(mWifiManager).stopSoftAp();
3032     }
3033 
3034     @Test
testStopTetheringWithSettingsPermission()3035     public void testStopTetheringWithSettingsPermission() throws Exception {
3036         assumeTrue(mTetheringDependencies.isTetheringWithSoftApConfigEnabled());
3037         initTetheringOnTestThread();
3038         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
3039         initTetheringUpstream(upstreamState);
3040 
3041         // Enable wifi tethering.
3042         SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
3043                 .setSsid("SoftApConfig")
3044                 .build();
3045         final TetheringRequest tetheringRequest = new TetheringRequest.Builder(TETHERING_WIFI)
3046                 .setSoftApConfiguration(softApConfig).build();
3047         tetheringRequest.setUid(TEST_CALLER_UID);
3048         mTethering.startTethering(tetheringRequest, TEST_CALLER_PKG, null);
3049         mLooper.dispatchAll();
3050 
3051         // Stop tethering with non-matching UID and Settings permission. Should succeed.
3052         final TetheringRequest nonMatchingUid = new TetheringRequest.Builder(TETHERING_WIFI)
3053                 .setSoftApConfiguration(softApConfig).build();
3054         IIntResultListener nonMatchingUidListener = mock(IIntResultListener.class);
3055         nonMatchingUid.setUid(TEST_CALLER_UID_2);
3056         when(mContext.checkCallingOrSelfPermission(NETWORK_SETTINGS))
3057                 .thenReturn(PERMISSION_GRANTED);
3058         mTethering.stopTetheringRequest(nonMatchingUid, nonMatchingUidListener);
3059         mLooper.dispatchAll();
3060         verify(nonMatchingUidListener).onResult(eq(TETHER_ERROR_NO_ERROR));
3061         verify(mWifiManager).stopSoftAp();
3062     }
3063 
3064     @Test
testReportFailCallbackIfOffloadNotSupported()3065     public void testReportFailCallbackIfOffloadNotSupported() throws Exception {
3066         initTetheringOnTestThread();
3067         final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
3068         TestTetheringEventCallback callback = new TestTetheringEventCallback();
3069         mTethering.registerTetheringEventCallback(callback);
3070         mLooper.dispatchAll();
3071         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
3072 
3073         // 1. Offload fail if no IOffloadHal.
3074         initOffloadConfiguration(OFFLOAD_HAL_VERSION_NONE, 0 /* defaultDisabled */);
3075         runUsbTethering(upstreamState);
3076         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
3077         runStopUSBTethering();
3078         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
3079         reset(mUsbManager, mIPv6TetheringCoordinator);
3080         // 2. Offload fail if disabled by settings.
3081         initOffloadConfiguration(OFFLOAD_HAL_VERSION_HIDL_1_0, 1 /* defaultDisabled */);
3082         runUsbTethering(upstreamState);
3083         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
3084         runStopUSBTethering();
3085         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
3086     }
3087 
runStopUSBTethering()3088     private void runStopUSBTethering() {
3089         mTethering.stopTethering(TETHERING_USB);
3090         mLooper.dispatchAll();
3091         sendUsbBroadcast(true, true, -1 /* function */);
3092         mLooper.dispatchAll();
3093         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3094     }
3095 
initOffloadConfiguration( @ffloadHardwareInterface.OffloadHalVersion final int offloadHalVersion, final int defaultDisabled)3096     private void initOffloadConfiguration(
3097             @OffloadHardwareInterface.OffloadHalVersion final int offloadHalVersion,
3098             final int defaultDisabled) {
3099         when(mOffloadHardwareInterface.initOffload(any())).thenReturn(offloadHalVersion);
3100         when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn(
3101                 defaultDisabled);
3102     }
3103 
3104     @Test
testMultiSimAware()3105     public void testMultiSimAware() throws Exception {
3106         initTetheringOnTestThread();
3107         final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
3108         assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId);
3109 
3110         final int fakeSubId = 1234;
3111         mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
3112         final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
3113         assertEquals(fakeSubId, newConfig.activeDataSubId);
3114         verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId));
3115     }
3116 
3117     @Test
testNoDuplicatedEthernetRequest()3118     public void testNoDuplicatedEthernetRequest() throws Exception {
3119         initTetheringOnTestThread();
3120         final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
3121         when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
3122         mTethering.startTethering(createTetheringRequest(TETHERING_ETHERNET), TEST_CALLER_PKG,
3123                 null);
3124         mLooper.dispatchAll();
3125         verify(mEm, times(1)).requestTetheredInterface(any(), any());
3126         mTethering.startTethering(createTetheringRequest(TETHERING_ETHERNET), TEST_CALLER_PKG,
3127                 null);
3128         mLooper.dispatchAll();
3129         verifyNoMoreInteractions(mEm);
3130         mTethering.stopTethering(TETHERING_ETHERNET);
3131         mLooper.dispatchAll();
3132         verify(mockRequest, times(1)).release();
3133         mTethering.stopTethering(TETHERING_ETHERNET);
3134         mLooper.dispatchAll();
3135         verifyNoMoreInteractions(mEm);
3136     }
3137 
workingWifiP2pGroupOwner( boolean emulateInterfaceStatusChanged)3138     private void workingWifiP2pGroupOwner(
3139             boolean emulateInterfaceStatusChanged) throws Exception {
3140         initTetheringOnTestThread();
3141         if (emulateInterfaceStatusChanged) {
3142             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
3143         }
3144         sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
3145 
3146         verifyInterfaceServingModeStarted(TEST_P2P_IFNAME, false);
3147         verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
3148         verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME);
3149         verify(mNetd, times(1)).tetherStartWithConfiguration(any());
3150         verifyNoMoreInteractions(mNetd);
3151         verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
3152         verify(mUpstreamNetworkMonitor, times(1)).startObserveUpstreamNetworks();
3153         // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY
3154         verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE);
3155 
3156         assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
3157 
3158         // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
3159         // is being removed.
3160         sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME);
3161         mTethering.interfaceRemoved(TEST_P2P_IFNAME);
3162 
3163         verify(mNetd, times(1)).tetherApplyDnsInterfaces();
3164         verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME);
3165         verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
3166         // interfaceSetCfg() called once for enabling and twice for disabling IPv4.
3167         verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
3168         verify(mNetd, times(1)).tetherStop();
3169         verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME);
3170         verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream();
3171         verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any());
3172         verifyNoMoreInteractions(mNetd);
3173         // Asking for the last error after the per-interface state machine
3174         // has been reaped yields an unknown interface error.
3175         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
3176     }
3177 
workingWifiP2pGroupClient( boolean emulateInterfaceStatusChanged)3178     private void workingWifiP2pGroupClient(
3179             boolean emulateInterfaceStatusChanged) throws Exception {
3180         initTetheringOnTestThread();
3181         if (emulateInterfaceStatusChanged) {
3182             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
3183         }
3184         sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME);
3185 
3186         verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
3187         verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
3188         verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
3189         verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
3190         verify(mNetd, never()).tetherStartWithConfiguration(any());
3191 
3192         // Emulate externally-visible WifiP2pManager effects, when wifi p2p group
3193         // is being removed.
3194         sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME);
3195         mTethering.interfaceRemoved(TEST_P2P_IFNAME);
3196 
3197         verify(mNetd, never()).tetherApplyDnsInterfaces();
3198         verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME);
3199         verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
3200         verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
3201         verify(mNetd, never()).tetherStop();
3202         verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME);
3203         verifyNoMoreInteractions(mNetd);
3204         // Asking for the last error after the per-interface state machine
3205         // has been reaped yields an unknown interface error.
3206         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
3207     }
3208 
3209     @Test
workingWifiP2pGroupOwnerWithIfaceChanged()3210     public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception {
3211         workingWifiP2pGroupOwner(true);
3212     }
3213 
3214     @Test
workingWifiP2pGroupOwnerSansIfaceChanged()3215     public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception {
3216         workingWifiP2pGroupOwner(false);
3217     }
3218 
workingWifiP2pGroupOwnerLegacyMode( boolean emulateInterfaceStatusChanged)3219     private void workingWifiP2pGroupOwnerLegacyMode(
3220             boolean emulateInterfaceStatusChanged) throws Exception {
3221         initTetheringOnTestThread();
3222         // change to legacy mode and update tethering information by chaning SIM
3223         when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
3224                 .thenReturn(new String[]{});
3225         final int fakeSubId = 1234;
3226         mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
3227 
3228         if (emulateInterfaceStatusChanged) {
3229             mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
3230         }
3231         sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
3232 
3233         verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class));
3234         verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME);
3235         verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME);
3236         verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME);
3237         verify(mNetd, never()).tetherStartWithConfiguration(any());
3238         assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
3239     }
3240     @Test
workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged()3241     public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception {
3242         workingWifiP2pGroupOwnerLegacyMode(true);
3243     }
3244 
3245     @Test
workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged()3246     public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception {
3247         workingWifiP2pGroupOwnerLegacyMode(false);
3248     }
3249 
3250     @Test
workingWifiP2pGroupClientWithIfaceChanged()3251     public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception {
3252         workingWifiP2pGroupClient(true);
3253     }
3254 
3255     @Test
workingWifiP2pGroupClientSansIfaceChanged()3256     public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception {
3257         workingWifiP2pGroupClient(false);
3258     }
3259 
setDataSaverEnabled(boolean enabled)3260     private void setDataSaverEnabled(boolean enabled) {
3261         final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED
3262                 : RESTRICT_BACKGROUND_STATUS_DISABLED;
3263         doReturn(status).when(mCm).getRestrictBackgroundStatus();
3264 
3265         final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED);
3266         mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL);
3267         mLooper.dispatchAll();
3268     }
3269 
3270     @Test
testDataSaverChanged()3271     public void testDataSaverChanged() throws Exception {
3272         initTetheringOnTestThread();
3273         // Start Tethering.
3274         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
3275         runUsbTethering(upstreamState);
3276         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
3277         // Data saver is ON.
3278         setDataSaverEnabled(true);
3279         // Verify that tethering should be disabled.
3280         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3281         sendUsbBroadcast(true, true, -1 /* function */);
3282         mLooper.dispatchAll();
3283         assertEquals(mTethering.getTetheredIfaces(), new String[0]);
3284         reset(mUsbManager, mIPv6TetheringCoordinator);
3285 
3286         runUsbTethering(upstreamState);
3287         // Verify that user can start tethering again without turning OFF data saver.
3288         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
3289 
3290         // If data saver is keep ON with change event, tethering should not be OFF this time.
3291         setDataSaverEnabled(true);
3292         verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3293         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
3294 
3295         // If data saver is turned OFF, it should not change tethering.
3296         setDataSaverEnabled(false);
3297         verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3298         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_RNDIS_IFNAME);
3299     }
3300 
assertContains(Collection<T> collection, T element)3301     private static <T> void assertContains(Collection<T> collection, T element) {
3302         assertTrue(element + " not found in " + collection, collection.contains(element));
3303     }
3304 
3305     private class ResultListener extends IIntResultListener.Stub {
3306         private final int mExpectedResult;
3307         private boolean mHasResult = false;
ResultListener(final int expectedResult)3308         ResultListener(final int expectedResult) {
3309             mExpectedResult = expectedResult;
3310         }
3311 
3312         @Override
onResult(final int resultCode)3313         public void onResult(final int resultCode) {
3314             mHasResult = true;
3315             if (resultCode != mExpectedResult) {
3316                 fail("expected result: " + mExpectedResult + " but actual result: " + resultCode);
3317             }
3318         }
3319 
assertHasResult()3320         public void assertHasResult() {
3321             if (!mHasResult) fail("No callback result");
3322         }
3323 
assertDoesNotHaveResult()3324         public void assertDoesNotHaveResult() {
3325             if (mHasResult) fail("Has callback result");
3326         }
3327     }
3328 
3329     @Test
testMultipleStartTetheringLegacy()3330     public void testMultipleStartTetheringLegacy() throws Exception {
3331         mTetheringWithSoftApConfigEnabled = false;
3332         initTetheringOnTestThread();
3333         final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
3334         final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
3335         final String serverAddr = "192.168.20.1";
3336         final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
3337         final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
3338         final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR);
3339 
3340         // Enable USB tethering and check that Tethering starts USB.
3341         mTethering.startTethering(createTetheringRequest(TETHERING_USB), TEST_CALLER_PKG,
3342                 firstResult);
3343         mLooper.dispatchAll();
3344         firstResult.assertHasResult();
3345         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
3346         verifyNoMoreInteractions(mUsbManager);
3347 
3348         // Enable USB tethering again with the same request and expect no change to USB.
3349         mTethering.startTethering(createTetheringRequest(TETHERING_USB), TEST_CALLER_PKG,
3350                 secondResult);
3351         mLooper.dispatchAll();
3352         secondResult.assertHasResult();
3353         verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3354         reset(mUsbManager);
3355 
3356         // Enable USB tethering again with the same request but different uid/package and expect no
3357         // change to USB.
3358         TetheringRequest differentUidPackage = createTetheringRequest(TETHERING_USB);
3359         differentUidPackage.setUid(TEST_CALLER_UID_2);
3360         differentUidPackage.setPackageName(TEST_CALLER_PKG_2);
3361         mTethering.startTethering(differentUidPackage, TEST_CALLER_PKG_2, secondResult);
3362         mLooper.dispatchAll();
3363         secondResult.assertHasResult();
3364         verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3365         reset(mUsbManager);
3366 
3367         // Enable USB tethering with a different request and expect that USB is stopped and
3368         // started.
3369         mTethering.startTethering(createTetheringRequest(TETHERING_USB,
3370                   serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL, null),
3371                   TEST_CALLER_PKG, thirdResult);
3372         mLooper.dispatchAll();
3373         thirdResult.assertHasResult();
3374         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3375         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
3376 
3377         // Expect that when USB comes up, the DHCP server is configured with the requested address.
3378         mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true);
3379         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
3380         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
3381                 any(), any());
3382         verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
3383     }
3384 
3385     @Test
testRequestStaticIp()3386     public void testRequestStaticIp() throws Exception {
3387         initTetheringOnTestThread();
3388         when(mResources.getInteger(R.integer.config_tether_usb_functions)).thenReturn(
3389                 TetheringConfiguration.TETHER_USB_NCM_FUNCTION);
3390         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
3391                 .thenReturn(new String[] {TEST_NCM_REGEX});
3392         sendConfigurationChanged();
3393 
3394         final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
3395         final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
3396         final String serverAddr = "192.168.0.123";
3397         final int clientAddrParceled = 0xc0a8002a;
3398         final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
3399                 ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
3400         mTethering.startTethering(createTetheringRequest(TETHERING_USB,
3401                   serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL, null),
3402                   TEST_CALLER_PKG, null);
3403         mLooper.dispatchAll();
3404         verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM);
3405         mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true);
3406         sendUsbBroadcast(true, true, TETHER_USB_NCM_FUNCTION);
3407         verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
3408         verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
3409                 any());
3410         final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
3411         assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
3412         assertEquals(24, params.serverAddrPrefixLength);
3413         assertEquals(clientAddrParceled, params.singleClientAddr);
3414     }
3415 
3416     @Test
3417     @IgnoreAfter(Build.VERSION_CODES.VANILLA_ICE_CREAM)
testRequestStaticIpLegacyTether()3418     public void testRequestStaticIpLegacyTether() throws Exception {
3419         initTetheringOnTestThread();
3420 
3421         // Call startTethering with static ip
3422         final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
3423         final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
3424         final String serverAddr = "192.168.0.123";
3425         final int clientAddrParceled = 0xc0a8002a;
3426         final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
3427                 ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
3428         mTethering.startTethering(createTetheringRequest(TETHERING_WIFI,
3429                         serverLinkAddr, clientLinkAddr, false, CONNECTIVITY_SCOPE_GLOBAL, null),
3430                 TEST_CALLER_PKG, null);
3431         mLooper.dispatchAll();
3432         verifyWifiTetheringRequested();
3433         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
3434 
3435         // Call legacyTether on the interface before the link layer event comes back.
3436         // This happens, for example, in pre-T bluetooth tethering: Settings calls startTethering,
3437         // and then the bluetooth code calls the tether() API.
3438         final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
3439         mTethering.legacyTether(TEST_WLAN_IFNAME, tetherResult);
3440         mLooper.dispatchAll();
3441         tetherResult.assertHasResult();
3442 
3443         // Verify that the static ip set in startTethering is used
3444         verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));
3445         verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
3446                 any());
3447         final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
3448         assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
3449         assertEquals(24, params.serverAddrPrefixLength);
3450         assertEquals(clientAddrParceled, params.singleClientAddr);
3451     }
3452 
3453     @Test
testUpstreamNetworkChanged()3454     public void testUpstreamNetworkChanged() throws Exception {
3455         initTetheringOnTestThread();
3456         final InOrder inOrder = inOrder(mNotificationUpdater);
3457 
3458         // Gain upstream.
3459         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
3460         initTetheringUpstream(upstreamState);
3461         mTetherMainSM.chooseUpstreamType(true);
3462         mTetheringEventCallback.expectUpstreamChanged(upstreamState.network);
3463         inOrder.verify(mNotificationUpdater)
3464                 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities);
3465 
3466         // Set the upstream with the same network ID but different object and the same capability.
3467         final UpstreamNetworkState upstreamState2 = buildMobileIPv4UpstreamState();
3468         initTetheringUpstream(upstreamState2);
3469         mTetherMainSM.chooseUpstreamType(true);
3470         // Expect that no upstream change event and capabilities changed event.
3471         mTetheringEventCallback.assertNoUpstreamChangeCallback();
3472         inOrder.verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any());
3473 
3474         // Set the upstream with the same network ID but different object and different capability.
3475         final UpstreamNetworkState upstreamState3 = buildMobileIPv4UpstreamState();
3476         assertFalse(upstreamState3.networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED));
3477         upstreamState3.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
3478         initTetheringUpstream(upstreamState3);
3479         mTetherMainSM.chooseUpstreamType(true);
3480         // Expect that no upstream change event and capabilities changed event.
3481         mTetheringEventCallback.assertNoUpstreamChangeCallback();
3482         mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState3);
3483         inOrder.verify(mNotificationUpdater)
3484                 .onUpstreamCapabilitiesChanged(upstreamState3.networkCapabilities);
3485 
3486 
3487         // Lose upstream.
3488         initTetheringUpstream(null);
3489         mTetherMainSM.chooseUpstreamType(true);
3490         mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK);
3491         inOrder.verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null);
3492     }
3493 
3494     @Test
testUpstreamCapabilitiesChanged()3495     public void testUpstreamCapabilitiesChanged() throws Exception {
3496         initTetheringOnTestThread();
3497         final InOrder inOrder = inOrder(mNotificationUpdater);
3498         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
3499         initTetheringUpstream(upstreamState);
3500 
3501         mTetherMainSM.chooseUpstreamType(true);
3502         inOrder.verify(mNotificationUpdater)
3503                 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities);
3504 
3505         mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
3506         inOrder.verify(mNotificationUpdater)
3507                 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities);
3508 
3509         // Verify that onUpstreamCapabilitiesChanged is called if current upstream network
3510         // capabilities changed.
3511         // Expect that capability is changed with new capability VALIDATED.
3512         assertFalse(upstreamState.networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED));
3513         upstreamState.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
3514         mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
3515         inOrder.verify(mNotificationUpdater)
3516                 .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities);
3517 
3518         // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network
3519         // capabilities changed.
3520         final UpstreamNetworkState upstreamState2 = new UpstreamNetworkState(
3521                 upstreamState.linkProperties, upstreamState.networkCapabilities,
3522                 new Network(WIFI_NETID));
3523         mTetherMainSM.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState2);
3524         inOrder.verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any());
3525     }
3526 
3527     @Test
testUpstreamCapabilitiesChanged_startStopTethering()3528     public void testUpstreamCapabilitiesChanged_startStopTethering() throws Exception {
3529         initTetheringOnTestThread();
3530         final TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState());
3531 
3532         // Start USB tethering with no current upstream.
3533         prepareUsbTethering();
3534         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
3535 
3536         // Pretend wifi connected and expect the upstream to be set.
3537         wifi.fakeConnect();
3538         mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST);
3539         mLooper.dispatchAll();
3540         verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(
3541                 wifi.networkCapabilities);
3542 
3543         // Stop tethering.
3544         // Expect that TetherModeAliveState#exit sends capabilities change notification to null.
3545         runStopUSBTethering();
3546         verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null);
3547     }
3548 
3549     @Test
testDumpTetheringLog()3550     public void testDumpTetheringLog() throws Exception {
3551         initTetheringOnTestThread();
3552         final FileDescriptor mockFd = mock(FileDescriptor.class);
3553         final PrintWriter mockPw = mock(PrintWriter.class);
3554         runUsbTethering(null);
3555         mTethering.dump(mockFd, mockPw, new String[0]);
3556         verify(mConfig).dump(any());
3557         verify(mEntitleMgr).dump(any());
3558         verify(mOffloadCtrl).dump(any());
3559     }
3560 
3561     @Test
testExemptFromEntitlementCheck()3562     public void testExemptFromEntitlementCheck() throws Exception {
3563         initTetheringOnTestThread();
3564         setupForRequiredProvisioning();
3565         final TetheringRequest wifiNotExemptRequest =
3566                 createTetheringRequest(TETHERING_WIFI, null, null, false,
3567                         CONNECTIVITY_SCOPE_GLOBAL, null);
3568         mTethering.startTethering(wifiNotExemptRequest, TEST_CALLER_PKG, null);
3569         mLooper.dispatchAll();
3570         verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
3571         verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
3572         assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
3573         mTethering.stopTethering(TETHERING_WIFI);
3574         mLooper.dispatchAll();
3575         verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
3576         reset(mEntitleMgr);
3577 
3578         setupForRequiredProvisioning();
3579         final TetheringRequest wifiExemptRequest =
3580                 createTetheringRequest(TETHERING_WIFI, null, null, true,
3581                         CONNECTIVITY_SCOPE_GLOBAL, null);
3582         mTethering.startTethering(wifiExemptRequest, TEST_CALLER_PKG, null);
3583         mLooper.dispatchAll();
3584         verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
3585         verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
3586         assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
3587         mTethering.stopTethering(TETHERING_WIFI);
3588         mLooper.dispatchAll();
3589         verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
3590         reset(mEntitleMgr);
3591     }
3592 
3593     @Test
testNonExemptRequestAddedAfterExemptRequestOfSameType()3594     public void testNonExemptRequestAddedAfterExemptRequestOfSameType() throws Exception {
3595         // Note: When fuzzy-matching is enabled, it is not possible yet to have two concurrent
3596         // requests of the same type that are subject to carrier entitlement due to fuzzy-matching.
3597         mTetheringWithSoftApConfigEnabled = false;
3598         initTetheringOnTestThread();
3599         setupForRequiredProvisioning();
3600         final TetheringRequest wifiExemptRequest =
3601                 createTetheringRequest(TETHERING_WIFI, null, null, true,
3602                         CONNECTIVITY_SCOPE_GLOBAL, null);
3603         mTethering.startTethering(wifiExemptRequest, TEST_CALLER_PKG, null);
3604         mLooper.dispatchAll();
3605         verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false);
3606         verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI);
3607         assertTrue(mEntitleMgr.isCellularUpstreamPermitted());
3608         reset(mEntitleMgr);
3609 
3610         setupForRequiredProvisioning();
3611         final TetheringRequest wifiNotExemptRequest =
3612                 createTetheringRequest(TETHERING_WIFI, null, null, false,
3613                         CONNECTIVITY_SCOPE_GLOBAL, null);
3614         mTethering.startTethering(wifiNotExemptRequest, TEST_CALLER_PKG, null);
3615         mLooper.dispatchAll();
3616         verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI);
3617         verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false);
3618         verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI);
3619         assertFalse(mEntitleMgr.isCellularUpstreamPermitted());
3620         mTethering.stopTethering(TETHERING_WIFI);
3621         mLooper.dispatchAll();
3622         verify(mEntitleMgr, times(2)).stopProvisioningIfNeeded(TETHERING_WIFI);
3623     }
3624 
setupForRequiredProvisioning()3625     private void setupForRequiredProvisioning() {
3626         // Produce some acceptable looking provision app setting if requested.
3627         when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
3628                 .thenReturn(PROVISIONING_APP_NAME);
3629         when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
3630                 .thenReturn(PROVISIONING_NO_UI_APP_NAME);
3631         // Act like the CarrierConfigManager is present and ready unless told otherwise.
3632         when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
3633                 .thenReturn(mCarrierConfigManager);
3634         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
3635         mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
3636         mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
3637         sendConfigurationChanged();
3638     }
3639 
buildV4UpstreamState(final LinkAddress address, final Network network, final String iface, final int transportType)3640     private static UpstreamNetworkState buildV4UpstreamState(final LinkAddress address,
3641             final Network network, final String iface, final int transportType) {
3642         final LinkProperties prop = new LinkProperties();
3643         prop.setInterfaceName(iface);
3644 
3645         prop.addLinkAddress(address);
3646 
3647         final NetworkCapabilities capabilities = new NetworkCapabilities()
3648                 .addTransportType(transportType);
3649         return new UpstreamNetworkState(prop, capabilities, network);
3650     }
3651 
updateV4Upstream(final LinkAddress ipv4Address, final Network network, final String iface, final int transportType)3652     private void updateV4Upstream(final LinkAddress ipv4Address, final Network network,
3653             final String iface, final int transportType) {
3654         final UpstreamNetworkState upstream = buildV4UpstreamState(ipv4Address, network, iface,
3655                 transportType);
3656         mEventListener.onUpstreamEvent(UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, upstream);
3657         mLooper.dispatchAll();
3658     }
3659 
3660     @Test
testHandleIpConflict()3661     public void testHandleIpConflict() throws Exception {
3662         initTetheringOnTestThread();
3663         final Network wifiNetwork = new Network(200);
3664         final Network[] allNetworks = { wifiNetwork };
3665         doReturn(allNetworks).when(mCm).getAllNetworks();
3666         InOrder inOrder = inOrder(mUsbManager, mNetd);
3667         runUsbTethering(null);
3668 
3669         inOrder.verify(mNetd).tetherInterfaceAdd(TEST_RNDIS_IFNAME);
3670 
3671         final ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor =
3672                 ArgumentCaptor.forClass(InterfaceConfigurationParcel.class);
3673         verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture());
3674         final String ipv4Address = ifaceConfigCaptor.getValue().ipv4Addr;
3675         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
3676                 any(), any());
3677 
3678         // Cause a prefix conflict by assigning a /30 out of the downstream's /24 to the upstream.
3679         updateV4Upstream(new LinkAddress(InetAddresses.parseNumericAddress(ipv4Address), 30),
3680                 wifiNetwork, TEST_WIFI_IFNAME, TRANSPORT_WIFI);
3681         // verify turn off usb tethering
3682         inOrder.verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3683         sendUsbBroadcast(true, true, -1 /* function */);
3684         mLooper.dispatchAll();
3685         inOrder.verify(mNetd).tetherInterfaceRemove(TEST_RNDIS_IFNAME);
3686 
3687         // verify restart usb tethering
3688         inOrder.verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
3689 
3690         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
3691         mLooper.dispatchAll();
3692         inOrder.verify(mNetd).tetherInterfaceAdd(TEST_RNDIS_IFNAME);
3693     }
3694 
3695     @Test
testNoAddressAvailable()3696     public void testNoAddressAvailable() throws Exception {
3697         initTetheringOnTestThread();
3698         final Network wifiNetwork = new Network(200);
3699         final Network btNetwork = new Network(201);
3700         final Network mobileNetwork = new Network(202);
3701         final Network[] allNetworks = { wifiNetwork, btNetwork, mobileNetwork };
3702         doReturn(allNetworks).when(mCm).getAllNetworks();
3703         runUsbTethering(null);
3704         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
3705                 any(), any());
3706         reset(mUsbManager);
3707         final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
3708         when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
3709         final ArgumentCaptor<TetheredInterfaceCallback> callbackCaptor =
3710                 ArgumentCaptor.forClass(TetheredInterfaceCallback.class);
3711         mTethering.startTethering(createTetheringRequest(TETHERING_ETHERNET),
3712                 TEST_CALLER_PKG, null);
3713         mLooper.dispatchAll();
3714         verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
3715         TetheredInterfaceCallback ethCallback = callbackCaptor.getValue();
3716         ethCallback.onAvailable(TEST_ETH_IFNAME);
3717         mLooper.dispatchAll();
3718         reset(mUsbManager, mEm);
3719 
3720         updateV4Upstream(new LinkAddress("192.168.0.100/16"), wifiNetwork, TEST_WIFI_IFNAME,
3721                 TRANSPORT_WIFI);
3722         updateV4Upstream(new LinkAddress("172.16.0.0/12"), btNetwork, TEST_BT_IFNAME,
3723                 TRANSPORT_BLUETOOTH);
3724         updateV4Upstream(new LinkAddress("10.0.0.0/8"), mobileNetwork, TEST_MOBILE_IFNAME,
3725                 TRANSPORT_CELLULAR);
3726 
3727         mLooper.dispatchAll();
3728         // verify turn off usb tethering
3729         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE);
3730         // verify turn off ethernet tethering
3731         verify(mockRequest).release();
3732         sendUsbBroadcast(true, true, -1 /* function */);
3733         ethCallback.onUnavailable();
3734         mLooper.dispatchAll();
3735         // verify restart usb tethering
3736         verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
3737         // verify restart ethernet tethering
3738         verify(mEm).requestTetheredInterface(any(), callbackCaptor.capture());
3739         ethCallback = callbackCaptor.getValue();
3740         ethCallback.onAvailable(TEST_ETH_IFNAME);
3741 
3742         reset(mUsbManager, mEm);
3743         when(mNetd.interfaceGetList())
3744                 .thenReturn(new String[] {
3745                         TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_RNDIS_IFNAME, TEST_P2P_IFNAME,
3746                         TEST_NCM_IFNAME, TEST_ETH_IFNAME});
3747 
3748         mTethering.interfaceStatusChanged(TEST_RNDIS_IFNAME, true);
3749         sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION);
3750         assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_RNDIS_IFNAME);
3751         assertContains(Arrays.asList(mTethering.getTetherableIfacesForTest()), TEST_ETH_IFNAME);
3752         assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest(
3753                 TEST_RNDIS_IFNAME));
3754         assertEquals(TETHER_ERROR_IFACE_CFG_ERROR, mTethering.getLastErrorForTest(TEST_ETH_IFNAME));
3755     }
3756 
3757     @Test
testProvisioningNeededButUnavailable()3758     public void testProvisioningNeededButUnavailable() throws Exception {
3759         initTetheringOnTestThread();
3760         assertTrue(mTethering.isTetheringSupported());
3761         verify(mPackageManager, never()).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
3762 
3763         setupForRequiredProvisioning();
3764         assertTrue(mTethering.isTetheringSupported());
3765         verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
3766         reset(mPackageManager);
3767 
3768         doThrow(PackageManager.NameNotFoundException.class).when(mPackageManager).getPackageInfo(
3769                 PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
3770         setupForRequiredProvisioning();
3771         assertFalse(mTethering.isTetheringSupported());
3772         verify(mPackageManager).getPackageInfo(PROVISIONING_APP_NAME[0], GET_ACTIVITIES);
3773     }
3774 
3775     @Test
testUpdateConnectedClients()3776     public void testUpdateConnectedClients() throws Exception {
3777         initTetheringOnTestThread();
3778         TestTetheringEventCallback callback = new TestTetheringEventCallback();
3779         runAsShell(NETWORK_SETTINGS, () -> {
3780             mTethering.registerTetheringEventCallback(callback);
3781             mLooper.dispatchAll();
3782         });
3783         callback.expectTetheredClientChanged(Collections.emptyList());
3784 
3785         IDhcpEventCallbacks eventCallbacks;
3786         final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor =
3787                  ArgumentCaptor.forClass(IDhcpEventCallbacks.class);
3788         // Run local only tethering.
3789         mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true);
3790         sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
3791         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
3792                 any(), dhcpEventCbsCaptor.capture());
3793         eventCallbacks = dhcpEventCbsCaptor.getValue();
3794         // Update lease for local only tethering.
3795         final MacAddress testMac1 = MacAddress.fromString("11:11:11:11:11:11");
3796         final DhcpLeaseParcelable p2pLease = createDhcpLeaseParcelable("clientId1", testMac1,
3797                 "192.168.50.24", 24, Long.MAX_VALUE, "test1");
3798         final List<TetheredClient> connectedClients = notifyDhcpLeasesChanged(TETHERING_WIFI_P2P,
3799                 eventCallbacks, p2pLease);
3800         callback.expectTetheredClientChanged(connectedClients);
3801         reset(mDhcpServer);
3802 
3803         // Run wifi tethering.
3804         TetheringRequest request = createTetheringRequest(TETHERING_WIFI);
3805         mTethering.startTethering(request, TEST_CALLER_PKG, null);
3806         mLooper.dispatchAll();
3807         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
3808         sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
3809         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
3810                 any(), dhcpEventCbsCaptor.capture());
3811         eventCallbacks = dhcpEventCbsCaptor.getValue();
3812         final MacAddress testMac2 = MacAddress.fromString("22:22:22:22:22:22");
3813         final DhcpLeaseParcelable wifiLease = createDhcpLeaseParcelable("clientId2", testMac2,
3814                 "192.168.43.24", 24, Long.MAX_VALUE, "test2");
3815         verifyHotspotClientUpdate(false /* isLocalOnly */, testMac2, wifiLease, connectedClients,
3816                 eventCallbacks, callback);
3817 
3818         // Test onStarted callback that register second callback when tethering is running.
3819         TestTetheringEventCallback callback2 = new TestTetheringEventCallback();
3820         runAsShell(NETWORK_SETTINGS, () -> {
3821             mTethering.registerTetheringEventCallback(callback2);
3822             mLooper.dispatchAll();
3823         });
3824         callback2.expectTetheredClientChanged(connectedClients);
3825     }
3826 
3827     @Test
3828     @IgnoreUpTo(Build.VERSION_CODES.S_V2)
testUpdateConnectedClientsForLocalOnlyHotspot()3829     public void testUpdateConnectedClientsForLocalOnlyHotspot() throws Exception {
3830         initTetheringOnTestThread();
3831         TestTetheringEventCallback callback = new TestTetheringEventCallback();
3832         runAsShell(NETWORK_SETTINGS, () -> {
3833             mTethering.registerTetheringEventCallback(callback);
3834             mLooper.dispatchAll();
3835         });
3836         callback.expectTetheredClientChanged(Collections.emptyList());
3837 
3838         // Run local only hotspot.
3839         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
3840         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
3841 
3842         final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor =
3843                  ArgumentCaptor.forClass(IDhcpEventCallbacks.class);
3844         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
3845                 any(), dhcpEventCbsCaptor.capture());
3846         final IDhcpEventCallbacks eventCallbacks = dhcpEventCbsCaptor.getValue();
3847 
3848         final List<TetheredClient> connectedClients = new ArrayList<>();
3849         final MacAddress testMac = MacAddress.fromString("22:22:22:22:22:22");
3850         final DhcpLeaseParcelable wifiLease = createDhcpLeaseParcelable("clientId", testMac,
3851                 "192.168.43.24", 24, Long.MAX_VALUE, "test");
3852         verifyHotspotClientUpdate(true /* isLocalOnly */, testMac, wifiLease, connectedClients,
3853                 eventCallbacks, callback);
3854 
3855         // Client disconnect from local only hotspot.
3856         mLocalOnlyHotspotCallback.onConnectedClientsChanged(Collections.emptyList());
3857         callback.expectTetheredClientChanged(Collections.emptyList());
3858     }
3859 
3860     @Test
3861     @IgnoreUpTo(Build.VERSION_CODES.S_V2)
testConnectedClientsForSapAndLohsConcurrency()3862     public void testConnectedClientsForSapAndLohsConcurrency() throws Exception {
3863         initTetheringOnTestThread();
3864         TestTetheringEventCallback callback = new TestTetheringEventCallback();
3865         runAsShell(NETWORK_SETTINGS, () -> {
3866             mTethering.registerTetheringEventCallback(callback);
3867             mLooper.dispatchAll();
3868         });
3869         callback.expectTetheredClientChanged(Collections.emptyList());
3870 
3871         TetheringRequest request = createTetheringRequest(TETHERING_WIFI);
3872         mTethering.startTethering(request, TEST_CALLER_PKG, null);
3873         mLooper.dispatchAll();
3874         verifyWifiTetheringRequested();
3875         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
3876         sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
3877         final ArgumentCaptor<IDhcpEventCallbacks> dhcpEventCbsCaptor =
3878                  ArgumentCaptor.forClass(IDhcpEventCallbacks.class);
3879         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
3880                 any(), dhcpEventCbsCaptor.capture());
3881         IDhcpEventCallbacks eventCallbacks = dhcpEventCbsCaptor.getValue();
3882         final List<TetheredClient> connectedClients = new ArrayList<>();
3883         final MacAddress wifiMac = MacAddress.fromString("11:11:11:11:11:11");
3884         final DhcpLeaseParcelable wifiLease = createDhcpLeaseParcelable("clientId", wifiMac,
3885                 "192.168.2.12", 24, Long.MAX_VALUE, "test");
3886         verifyHotspotClientUpdate(false /* isLocalOnly */, wifiMac, wifiLease, connectedClients,
3887                 eventCallbacks, callback);
3888         reset(mDhcpServer);
3889 
3890         mTethering.interfaceStatusChanged(TEST_WLAN2_IFNAME, true);
3891         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN2_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
3892 
3893         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
3894                 any(), dhcpEventCbsCaptor.capture());
3895         eventCallbacks = dhcpEventCbsCaptor.getValue();
3896         final MacAddress localOnlyMac = MacAddress.fromString("22:22:22:22:22:22");
3897         final DhcpLeaseParcelable localOnlyLease = createDhcpLeaseParcelable("clientId",
3898                 localOnlyMac, "192.168.43.24", 24, Long.MAX_VALUE, "test");
3899         verifyHotspotClientUpdate(true /* isLocalOnly */, localOnlyMac, localOnlyLease,
3900                 connectedClients, eventCallbacks, callback);
3901 
3902         assertTrue(isIpServerActive(TETHERING_WIFI, TEST_WLAN_IFNAME, IpServer.STATE_TETHERED));
3903         assertTrue(isIpServerActive(TETHERING_WIFI, TEST_WLAN2_IFNAME, IpServer.STATE_LOCAL_ONLY));
3904     }
3905 
isIpServerActive(int type, String ifName, int mode)3906     private boolean isIpServerActive(int type, String ifName, int mode) {
3907         for (IpServer ipSrv : mTetheringDependencies.mAllDownstreams) {
3908             if (ipSrv.interfaceType() == type && ipSrv.interfaceName().equals(ifName)
3909                     && ipSrv.servingMode() == mode) {
3910                 return true;
3911             }
3912         }
3913 
3914         return false;
3915     }
3916 
verifyHotspotClientUpdate(final boolean isLocalOnly, final MacAddress testMac, final DhcpLeaseParcelable dhcpLease, final List<TetheredClient> currentClients, final IDhcpEventCallbacks dhcpCallback, final TestTetheringEventCallback callback)3917     private void verifyHotspotClientUpdate(final boolean isLocalOnly, final MacAddress testMac,
3918             final DhcpLeaseParcelable dhcpLease, final List<TetheredClient> currentClients,
3919             final IDhcpEventCallbacks dhcpCallback, final TestTetheringEventCallback callback)
3920             throws Exception {
3921         // Update mac address from softAp callback before getting dhcp lease.
3922         final TetheredClient noAddrClient = notifyConnectedWifiClientsChanged(testMac, isLocalOnly);
3923         final List<TetheredClient> withNoAddrClients = new ArrayList<>(currentClients);
3924         withNoAddrClients.add(noAddrClient);
3925         callback.expectTetheredClientChanged(withNoAddrClients);
3926 
3927         // Update dhcp lease for hotspot.
3928         currentClients.addAll(notifyDhcpLeasesChanged(TETHERING_WIFI, dhcpCallback, dhcpLease));
3929         callback.expectTetheredClientChanged(currentClients);
3930     }
3931 
notifyConnectedWifiClientsChanged(final MacAddress mac, boolean isLocalOnly)3932     private TetheredClient notifyConnectedWifiClientsChanged(final MacAddress mac,
3933             boolean isLocalOnly) throws Exception {
3934         final ArrayList<WifiClient> wifiClients = new ArrayList<>();
3935         final WifiClient testClient = mock(WifiClient.class);
3936         when(testClient.getMacAddress()).thenReturn(mac);
3937         wifiClients.add(testClient);
3938         if (isLocalOnly) {
3939             mLocalOnlyHotspotCallback.onConnectedClientsChanged(wifiClients);
3940         } else {
3941             mSoftApCallback.onConnectedClientsChanged(wifiClients);
3942         }
3943         return new TetheredClient(mac, Collections.emptyList() /* addresses */, TETHERING_WIFI);
3944     }
3945 
notifyDhcpLeasesChanged(int type, IDhcpEventCallbacks callback, DhcpLeaseParcelable... leases)3946     private List<TetheredClient> notifyDhcpLeasesChanged(int type, IDhcpEventCallbacks callback,
3947             DhcpLeaseParcelable... leases) throws Exception {
3948         final List<DhcpLeaseParcelable> dhcpLeases = Arrays.asList(leases);
3949         callback.onLeasesChanged(dhcpLeases);
3950         mLooper.dispatchAll();
3951 
3952         return toTetheredClients(dhcpLeases, type);
3953     }
3954 
toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables, int type)3955     private List<TetheredClient> toTetheredClients(List<DhcpLeaseParcelable> leaseParcelables,
3956             int type) throws Exception {
3957         final ArrayList<TetheredClient> clients = new ArrayList<>();
3958         for (DhcpLeaseParcelable lease : leaseParcelables) {
3959             final LinkAddress address = new LinkAddress(
3960                     intToInet4AddressHTH(lease.netAddr), lease.prefixLength,
3961                     0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */,
3962                     lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */);
3963 
3964             final MacAddress macAddress = MacAddress.fromBytes(lease.hwAddr);
3965 
3966             final AddressInfo addressInfo = new TetheredClient.AddressInfo(address, lease.hostname);
3967             clients.add(new TetheredClient(
3968                     macAddress,
3969                     Collections.singletonList(addressInfo),
3970                     type));
3971         }
3972 
3973         return clients;
3974     }
3975 
createDhcpLeaseParcelable(final String clientId, final MacAddress hwAddr, final String netAddr, final int prefixLength, final long expTime, final String hostname)3976     private DhcpLeaseParcelable createDhcpLeaseParcelable(final String clientId,
3977             final MacAddress hwAddr, final String netAddr, final int prefixLength,
3978             final long expTime, final String hostname) throws Exception {
3979         final DhcpLeaseParcelable lease = new DhcpLeaseParcelable();
3980         lease.clientId = clientId.getBytes();
3981         lease.hwAddr = hwAddr.toByteArray();
3982         lease.netAddr = inet4AddressToIntHTH(
3983                 (Inet4Address) InetAddresses.parseNumericAddress(netAddr));
3984         lease.prefixLength = prefixLength;
3985         lease.expTime = expTime;
3986         lease.hostname = hostname;
3987 
3988         return lease;
3989     }
3990 
3991     @Test
3992     @IgnoreUpTo(Build.VERSION_CODES.S_V2)
testBluetoothTethering()3993     public void testBluetoothTethering() throws Exception {
3994         initTetheringOnTestThread();
3995 
3996         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
3997         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
3998         mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
3999                 TEST_CALLER_PKG, result);
4000         mLooper.dispatchAll();
4001         verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
4002         result.assertHasResult();
4003 
4004         mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
4005         mLooper.dispatchAll();
4006         verifyNetdCommandForBtSetup();
4007 
4008         // If PAN disconnect, tethering should also be stopped.
4009         mTetheredInterfaceCallbackShim.onUnavailable();
4010         mLooper.dispatchAll();
4011         verifyNetdCommandForBtTearDown();
4012 
4013         // Tethering could restart if PAN reconnect.
4014         mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
4015         mLooper.dispatchAll();
4016         verifyNetdCommandForBtSetup();
4017 
4018         // Pretend that bluetooth tethering was disabled.
4019         mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */);
4020         mTethering.stopTethering(TETHERING_BLUETOOTH);
4021         mLooper.dispatchAll();
4022         verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */);
4023 
4024         verifyNetdCommandForBtTearDown();
4025     }
4026 
4027     @Test
4028     @IgnoreAfter(Build.VERSION_CODES.S_V2)
testBluetoothTetheringBeforeT()4029     public void testBluetoothTetheringBeforeT() throws Exception {
4030         initTetheringOnTestThread();
4031 
4032         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
4033         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
4034         mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
4035                 TEST_CALLER_PKG, result);
4036         mLooper.dispatchAll();
4037         verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
4038         result.assertHasResult();
4039 
4040         mTethering.interfaceAdded(TEST_BT_IFNAME);
4041         mLooper.dispatchAll();
4042 
4043         mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
4044         mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
4045         final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
4046         mTethering.legacyTether(TEST_BT_IFNAME, tetherResult);
4047         mLooper.dispatchAll();
4048         tetherResult.assertHasResult();
4049 
4050         verifyNetdCommandForBtSetup();
4051 
4052         // Turning tethering on a second time does not bind to the PAN service again, since it's
4053         // already bound.
4054         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
4055         final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR);
4056         mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
4057                 TEST_CALLER_PKG, secondResult);
4058         mLooper.dispatchAll();
4059         verifySetBluetoothTethering(true /* enable */, false /* bindToPanService */);
4060         secondResult.assertHasResult();
4061 
4062         mockBluetoothSettings(true /* bluetoothOn */, false /* tetheringOn */);
4063         mTethering.stopTethering(TETHERING_BLUETOOTH);
4064         mLooper.dispatchAll();
4065         final ResultListener untetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
4066         mTethering.legacyUntether(TEST_BT_IFNAME, untetherResult);
4067         mLooper.dispatchAll();
4068         untetherResult.assertHasResult();
4069         verifySetBluetoothTethering(false /* enable */, false /* bindToPanService */);
4070 
4071         verifyNetdCommandForBtTearDown();
4072     }
4073 
4074     @Test
testBluetoothServiceDisconnects()4075     public void testBluetoothServiceDisconnects() throws Exception {
4076         initTetheringOnTestThread();
4077         final ResultListener result = new ResultListener(TETHER_ERROR_NO_ERROR);
4078         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
4079         mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
4080                 TEST_CALLER_PKG, result);
4081         mLooper.dispatchAll();
4082         ServiceListener panListener = verifySetBluetoothTethering(true /* enable */,
4083                 true /* bindToPanService */);
4084         result.assertHasResult();
4085 
4086         mTethering.interfaceAdded(TEST_BT_IFNAME);
4087         mLooper.dispatchAll();
4088 
4089         if (isAtLeastT()) {
4090             mTetheredInterfaceCallbackShim.onAvailable(TEST_BT_IFNAME);
4091             mLooper.dispatchAll();
4092         } else {
4093             mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
4094             mTethering.interfaceStatusChanged(TEST_BT_IFNAME, true);
4095             final ResultListener tetherResult = new ResultListener(TETHER_ERROR_NO_ERROR);
4096             mTethering.legacyTether(TEST_BT_IFNAME, tetherResult);
4097             mLooper.dispatchAll();
4098             tetherResult.assertHasResult();
4099         }
4100 
4101         verifyNetdCommandForBtSetup();
4102 
4103         panListener.onServiceDisconnected(BluetoothProfile.PAN);
4104         mTethering.interfaceStatusChanged(TEST_BT_IFNAME, false);
4105         mLooper.dispatchAll();
4106 
4107         verifyNetdCommandForBtTearDown();
4108     }
4109 
4110     @Test
testPendingPanEnableRequestFailedUponDisableRequest()4111     public void testPendingPanEnableRequestFailedUponDisableRequest() throws Exception {
4112         initTetheringOnTestThread();
4113 
4114         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
4115         final ResultListener failedEnable = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL);
4116         mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
4117                 TEST_CALLER_PKG, failedEnable);
4118         mLooper.dispatchAll();
4119         failedEnable.assertDoesNotHaveResult();
4120 
4121         // Stop tethering before the pan service connects. This should fail the enable request.
4122         mTethering.stopTethering(TETHERING_BLUETOOTH);
4123         mLooper.dispatchAll();
4124         failedEnable.assertHasResult();
4125     }
4126 
4127     @Test
testStartBluetoothTetheringFailsWhenTheresAnExistingRequestWaitingForPanService()4128     public void testStartBluetoothTetheringFailsWhenTheresAnExistingRequestWaitingForPanService()
4129             throws Exception {
4130         mTetheringWithSoftApConfigEnabled = false;
4131         initTetheringOnTestThread();
4132 
4133         mockBluetoothSettings(true /* bluetoothOn */, true /* tetheringOn */);
4134         final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR);
4135         mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
4136                 TEST_CALLER_PKG, firstResult);
4137         mLooper.dispatchAll();
4138         firstResult.assertDoesNotHaveResult();
4139 
4140         // Second request should fail.
4141         final ResultListener secondResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL);
4142         mTethering.startTethering(createTetheringRequest(TETHERING_BLUETOOTH),
4143                 TEST_CALLER_PKG, secondResult);
4144         mLooper.dispatchAll();
4145         secondResult.assertHasResult();
4146         firstResult.assertDoesNotHaveResult();
4147 
4148         // Bind to PAN service should succeed for first listener only. If the second result is
4149         // called with TETHER_ERROR_NO_ERROR, ResultListener will fail an assertion.
4150         verifySetBluetoothTethering(true /* enable */, true /* bindToPanService */);
4151         firstResult.assertHasResult();
4152     }
4153 
mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn)4154     private void mockBluetoothSettings(boolean bluetoothOn, boolean tetheringOn) {
4155         when(mBluetoothAdapter.isEnabled()).thenReturn(bluetoothOn);
4156         when(mBluetoothPan.isTetheringOn()).thenReturn(tetheringOn);
4157     }
4158 
verifyNetdCommandForBtSetup()4159     private void verifyNetdCommandForBtSetup() throws Exception {
4160         if (isAtLeastT()) {
4161             verify(mNetd).interfaceSetCfg(argThat(cfg -> TEST_BT_IFNAME.equals(cfg.ifName)
4162                     && assertContainsFlag(cfg.flags, INetd.IF_STATE_UP)));
4163         }
4164         verify(mNetd).tetherInterfaceAdd(TEST_BT_IFNAME);
4165         if (isTetheringNetworkAgentFeatureEnabled()) {
4166             verify(mNetd, never()).networkAddInterface(anyInt(), anyString());
4167             verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString());
4168         } else {
4169             verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME);
4170             verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME),
4171                     anyString(), anyString());
4172         }
4173         verify(mNetd).ipfwdEnableForwarding(TETHERING_NAME);
4174         verify(mNetd).tetherStartWithConfiguration(any());
4175         if (isTetheringNetworkAgentFeatureEnabled()) {
4176             verify(mNetd, never()).networkAddRoute(anyInt(), anyString(), anyString(), anyString());
4177         } else {
4178             verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_BT_IFNAME),
4179                     anyString(), anyString());
4180         }
4181         verifyNoMoreInteractions(mNetd);
4182         reset(mNetd);
4183     }
4184 
assertContainsFlag(String[] flags, String match)4185     private boolean assertContainsFlag(String[] flags, String match) {
4186         for (String flag : flags) {
4187             if (flag.equals(match)) return true;
4188         }
4189         return false;
4190     }
4191 
verifyNetdCommandForBtTearDown()4192     private void verifyNetdCommandForBtTearDown() throws Exception {
4193         verify(mNetd).tetherApplyDnsInterfaces();
4194         verify(mNetd).tetherInterfaceRemove(TEST_BT_IFNAME);
4195         if (isTetheringNetworkAgentFeatureEnabled()) {
4196             verify(mNetd, never()).networkRemoveInterface(anyInt(), anyString());
4197         } else {
4198             verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_BT_IFNAME);
4199         }
4200         // One is ipv4 address clear (set to 0.0.0.0), another is set interface down which only
4201         // happen after T. Before T, the interface configuration control in bluetooth side.
4202         verify(mNetd, times(isAtLeastT() ? 2 : 1)).interfaceSetCfg(
4203                 any(InterfaceConfigurationParcel.class));
4204         verify(mNetd).tetherStop();
4205         verify(mNetd).ipfwdDisableForwarding(TETHERING_NAME);
4206         reset(mNetd);
4207     }
4208 
4209     // If bindToPanService is true, this function would return ServiceListener which could notify
4210     // PanService is connected or disconnected.
verifySetBluetoothTethering(final boolean enable, final boolean bindToPanService)4211     private ServiceListener verifySetBluetoothTethering(final boolean enable,
4212             final boolean bindToPanService) throws Exception {
4213         ServiceListener listener = null;
4214         verify(mBluetoothAdapter, atLeastOnce()).isEnabled();
4215         if (bindToPanService) {
4216             final ArgumentCaptor<ServiceListener> listenerCaptor =
4217                     ArgumentCaptor.forClass(ServiceListener.class);
4218             verify(mBluetoothAdapter).getProfileProxy(eq(mServiceContext), listenerCaptor.capture(),
4219                     eq(BluetoothProfile.PAN));
4220             listener = listenerCaptor.getValue();
4221             listener.onServiceConnected(BluetoothProfile.PAN, mBluetoothPan);
4222             mLooper.dispatchAll();
4223         } else {
4224             verify(mBluetoothAdapter, never()).getProfileProxy(eq(mServiceContext), any(),
4225                     anyInt());
4226         }
4227 
4228         if (isAtLeastT()) {
4229             if (enable) {
4230                 final ArgumentCaptor<TetheredInterfaceCallbackShim> callbackCaptor =
4231                         ArgumentCaptor.forClass(TetheredInterfaceCallbackShim.class);
4232                 verify(mBluetoothPanShim).requestTetheredInterface(any(), callbackCaptor.capture());
4233                 mTetheredInterfaceCallbackShim = callbackCaptor.getValue();
4234             } else {
4235                 verify(mTetheredInterfaceRequestShim).release();
4236             }
4237         } else {
4238             verify(mBluetoothPan).setBluetoothTethering(enable);
4239         }
4240         verify(mBluetoothPan).isTetheringOn();
4241         verifyNoMoreInteractions(mBluetoothAdapter, mBluetoothPan);
4242         reset(mBluetoothAdapter, mBluetoothPan);
4243 
4244         return listener;
4245     }
4246 
runDualStackUsbTethering(final String expectedIface)4247     private void runDualStackUsbTethering(final String expectedIface) throws Exception {
4248         when(mNetd.interfaceGetList()).thenReturn(new String[] {expectedIface});
4249         when(mRouterAdvertisementDaemon.start())
4250                 .thenReturn(true);
4251         final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
4252         runUsbTethering(upstreamState);
4253 
4254         verify(mNetd).interfaceGetList();
4255         verify(mRoutingCoordinatorManager).addInterfaceForward(expectedIface, TEST_MOBILE_IFNAME);
4256 
4257         verify(mRouterAdvertisementDaemon).start();
4258         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS)).startWithCallbacks(
4259                 any(), any());
4260         sendIPv6TetherUpdates(upstreamState);
4261         assertSetIfaceToDadProxy(1 /* numOfCalls */, TEST_MOBILE_IFNAME /* ifaceName */);
4262         verify(mRouterAdvertisementDaemon).buildNewRa(any(), notNull());
4263         verify(mNetd).tetherApplyDnsInterfaces();
4264     }
4265 
forceUsbTetheringUse(final int function)4266     private void forceUsbTetheringUse(final int function) {
4267         setSetting(TETHER_FORCE_USB_FUNCTIONS, function);
4268     }
4269 
setSetting(final String key, final int value)4270     private void setSetting(final String key, final int value) {
4271         Settings.Global.putInt(mContentResolver, key, value);
4272         final ContentObserver observer = mTethering.getSettingsObserverForTest();
4273         observer.onChange(false /* selfChange */, Settings.Global.getUriFor(key));
4274         mLooper.dispatchAll();
4275     }
4276 
verifyUsbTetheringStopDueToSettingChange(final String iface)4277     private void verifyUsbTetheringStopDueToSettingChange(final String iface) {
4278         verify(mUsbManager, times(2)).setCurrentFunctions(UsbManager.FUNCTION_NONE);
4279         mTethering.interfaceRemoved(iface);
4280         sendUsbBroadcast(true, true, -1 /* no functions enabled */);
4281         reset(mUsbManager, mNetd, mDhcpServer, mRouterAdvertisementDaemon,
4282                 mIPv6TetheringCoordinator, mDadProxy);
4283     }
4284 
4285     @Test
testUsbFunctionConfigurationChange()4286     public void testUsbFunctionConfigurationChange() throws Exception {
4287         initTetheringOnTestThread();
4288         // Run TETHERING_NCM.
4289         runNcmTethering();
4290         verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks(
4291                 any(), any());
4292         verify(mTetheringMetrics).createBuilder(eq(TETHERING_NCM), anyString());
4293         verify(mTetheringMetrics, times(1)).maybeUpdateUpstreamType(any());
4294 
4295         // Change the USB tethering function to NCM. Because the USB tethering function was set to
4296         // RNDIS (the default), tethering is stopped.
4297         forceUsbTetheringUse(TETHER_USB_NCM_FUNCTION);
4298         verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME);
4299         verify(mTetheringMetrics).updateErrorCode(anyInt(), eq(TETHER_ERROR_NO_ERROR));
4300         verify(mTetheringMetrics).sendReport(eq(TETHERING_NCM));
4301 
4302         // If TETHERING_USB is forced to use ncm function, TETHERING_NCM would no longer be
4303         // available.
4304         final ResultListener ncmResult = new ResultListener(TETHER_ERROR_SERVICE_UNAVAIL);
4305         mTethering.startTethering(createTetheringRequest(TETHERING_NCM), TEST_CALLER_PKG,
4306                 ncmResult);
4307         mLooper.dispatchAll();
4308         ncmResult.assertHasResult();
4309         verify(mTetheringMetrics, times(2)).createBuilder(eq(TETHERING_NCM), anyString());
4310         verify(mTetheringMetrics, times(1)).maybeUpdateUpstreamType(any());
4311         verify(mTetheringMetrics).updateErrorCode(eq(TETHERING_NCM),
4312                 eq(TETHER_ERROR_SERVICE_UNAVAIL));
4313         verify(mTetheringMetrics, times(2)).sendReport(eq(TETHERING_NCM));
4314 
4315         // Run TETHERING_USB with ncm configuration.
4316         runDualStackUsbTethering(TEST_NCM_IFNAME);
4317 
4318         // Change configuration to rndis.
4319         forceUsbTetheringUse(TETHER_USB_RNDIS_FUNCTION);
4320         verifyUsbTetheringStopDueToSettingChange(TEST_NCM_IFNAME);
4321 
4322         // Run TETHERING_USB with rndis configuration.
4323         runDualStackUsbTethering(TEST_RNDIS_IFNAME);
4324         runStopUSBTethering();
4325     }
4326 
getAllSupportedTetheringTypes()4327     public static ArraySet<Integer> getAllSupportedTetheringTypes() {
4328         return new ArraySet<>(new Integer[] { TETHERING_USB, TETHERING_NCM, TETHERING_WIFI,
4329                 TETHERING_WIFI_P2P, TETHERING_BLUETOOTH, TETHERING_ETHERNET });
4330     }
4331 
setUserRestricted(boolean restricted)4332     private void setUserRestricted(boolean restricted) {
4333         final Bundle restrictions = new Bundle();
4334         restrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, restricted);
4335         when(mUserManager.getUserRestrictions()).thenReturn(restrictions);
4336         when(mUserManager.hasUserRestriction(
4337                 UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(restricted);
4338 
4339         final Intent intent = new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
4340         mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4341         mLooper.dispatchAll();
4342     }
4343 
4344     @Test
testTetheringSupported()4345     public void testTetheringSupported() throws Exception {
4346         initTetheringOnTestThread();
4347         final ArraySet<Integer> expectedTypes = getAllSupportedTetheringTypes();
4348         // Check tethering is supported after initialization.
4349         TestTetheringEventCallback callback = new TestTetheringEventCallback();
4350         mTethering.registerTetheringEventCallback(callback);
4351         mLooper.dispatchAll();
4352         verifySupported(callback, expectedTypes);
4353 
4354         // Could change tethering supported by settings.
4355         setSetting(Settings.Global.TETHER_SUPPORTED, 0);
4356         verifySupported(callback, new ArraySet<>());
4357         setSetting(Settings.Global.TETHER_SUPPORTED, 1);
4358         verifySupported(callback, expectedTypes);
4359 
4360         // Could change tethering supported by user restriction.
4361         setUserRestricted(true /* restricted */);
4362         verifySupported(callback, new ArraySet<>());
4363         setUserRestricted(false /* restricted */);
4364         verifySupported(callback, expectedTypes);
4365 
4366         // Usb tethering is not supported:
4367         expectedTypes.remove(TETHERING_USB);
4368         when(mResources.getStringArray(R.array.config_tether_usb_regexs))
4369                 .thenReturn(new String[0]);
4370         sendConfigurationChanged();
4371         verifySupported(callback, expectedTypes);
4372         // Wifi tethering is not supported:
4373         expectedTypes.remove(TETHERING_WIFI);
4374         when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
4375                 .thenReturn(new String[0]);
4376         sendConfigurationChanged();
4377         verifySupported(callback, expectedTypes);
4378         // Bluetooth tethering is not supported:
4379         expectedTypes.remove(TETHERING_BLUETOOTH);
4380         when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
4381                 .thenReturn(new String[0]);
4382 
4383         if (isAtLeastT()) {
4384             sendConfigurationChanged();
4385             verifySupported(callback, expectedTypes);
4386 
4387             // P2p tethering is not supported:
4388             expectedTypes.remove(TETHERING_WIFI_P2P);
4389             when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
4390                     .thenReturn(new String[0]);
4391             sendConfigurationChanged();
4392             verifySupported(callback, expectedTypes);
4393             // Ncm tethering is not supported:
4394             expectedTypes.remove(TETHERING_NCM);
4395             when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
4396                     .thenReturn(new String[0]);
4397             sendConfigurationChanged();
4398             verifySupported(callback, expectedTypes);
4399             // Ethernet tethering (last supported type) is not supported:
4400             expectedTypes.remove(TETHERING_ETHERNET);
4401             mForceEthernetServiceUnavailable = true;
4402             sendConfigurationChanged();
4403             verifySupported(callback, new ArraySet<>());
4404         } else {
4405             // If wifi, usb and bluetooth are all not supported, all the types are not supported.
4406             sendConfigurationChanged();
4407             verifySupported(callback, new ArraySet<>());
4408         }
4409     }
4410 
verifySupported(final TestTetheringEventCallback callback, final ArraySet<Integer> expectedTypes)4411     private void verifySupported(final TestTetheringEventCallback callback,
4412             final ArraySet<Integer> expectedTypes) {
4413         assertEquals(expectedTypes.size() > 0, mTethering.isTetheringSupported());
4414         callback.expectSupportedTetheringTypes(expectedTypes);
4415     }
4416 
4417     @Test
testIpv4AddressForSapAndLohsConcurrency()4418     public void testIpv4AddressForSapAndLohsConcurrency() throws Exception {
4419         initTetheringOnTestThread();
4420         TetheringRequest request = createTetheringRequest(TETHERING_WIFI);
4421         mTethering.startTethering(request, TEST_CALLER_PKG, null);
4422         mLooper.dispatchAll();
4423         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
4424         sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
4425 
4426         ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor =
4427                 ArgumentCaptor.forClass(InterfaceConfigurationParcel.class);
4428         verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture());
4429         InterfaceConfigurationParcel ifaceConfig = ifaceConfigCaptor.getValue();
4430         final IpPrefix sapPrefix = new IpPrefix(
4431                 InetAddresses.parseNumericAddress(ifaceConfig.ipv4Addr), ifaceConfig.prefixLength);
4432 
4433         mTethering.interfaceStatusChanged(TEST_WLAN2_IFNAME, true);
4434         sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN2_IFNAME, IFACE_IP_MODE_LOCAL_ONLY);
4435 
4436         ifaceConfigCaptor = ArgumentCaptor.forClass(InterfaceConfigurationParcel.class);
4437         verify(mNetd, times(2)).interfaceSetCfg(ifaceConfigCaptor.capture());
4438         ifaceConfig = ifaceConfigCaptor.getValue();
4439         final IpPrefix lohsPrefix = new IpPrefix(
4440                 InetAddresses.parseNumericAddress(ifaceConfig.ipv4Addr), ifaceConfig.prefixLength);
4441         assertFalse(sapPrefix.equals(lohsPrefix));
4442     }
4443 
4444     @Test
testFailStartTetheredHotspotWithoutRequest()4445     public void testFailStartTetheredHotspotWithoutRequest() throws Exception {
4446         mTetheringWithSoftApConfigEnabled = false;
4447         initTetheringOnTestThread();
4448         when(mWifiManager.startTetheredHotspot(null)).thenReturn(false);
4449 
4450         ResultListener result = new ResultListener(TETHER_ERROR_INTERNAL_ERROR);
4451         mTethering.startTethering(createTetheringRequest(TETHERING_WIFI), TEST_CALLER_PKG, result);
4452         mLooper.dispatchAll();
4453         verify(mWifiManager).startTetheredHotspot(null);
4454         verifyNoMoreInteractions(mWifiManager);
4455         result.assertHasResult();
4456         assertTrue(mTethering.getPendingTetheringRequests().isEmpty());
4457     }
4458 
4459     @Test
testWifiTetheringWhenP2pActive()4460     public void testWifiTetheringWhenP2pActive() throws Exception {
4461         initTetheringOnTestThread();
4462         // Enable wifi P2P.
4463         sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME);
4464         verifyInterfaceServingModeStarted(TEST_P2P_IFNAME, false);
4465         verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER);
4466         verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
4467         verify(mUpstreamNetworkMonitor).startObserveUpstreamNetworks();
4468         // Verify never enable upstream if only P2P active.
4469         verify(mUpstreamNetworkMonitor, never()).setTryCell(true);
4470         assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastErrorForTest(TEST_P2P_IFNAME));
4471 
4472         // Emulate pressing the WiFi tethering button.
4473         TetheringRequest request = createTetheringRequest(TETHERING_WIFI);
4474         mTethering.startTethering(request, TEST_CALLER_PKG, null);
4475         mLooper.dispatchAll();
4476         verifyWifiTetheringRequested();
4477 
4478         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
4479         sendSoftApEvent(WIFI_AP_STATE_ENABLED, request, TEST_WLAN_IFNAME);
4480 
4481         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER);
4482         verify(mWifiManager).updateInterfaceIpState(
4483                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
4484 
4485         verify(mWifiManager).updateInterfaceIpState(TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
4486         verifyNoMoreInteractions(mWifiManager);
4487         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
4488 
4489         verify(mUpstreamNetworkMonitor).setTryCell(true);
4490     }
4491 
4492     // TODO: Test that a request for hotspot mode doesn't interfere with an
4493     // already operating tethering mode interface.
4494 
4495     @Test
testVirtualTetheringWithInterfaceName()4496     public void testVirtualTetheringWithInterfaceName() throws Exception {
4497         initTetheringOnTestThread();
4498         final TetheringRequest virtualTetheringRequest =
4499                 createTetheringRequest(TETHERING_VIRTUAL, null, null, false,
4500                         CONNECTIVITY_SCOPE_GLOBAL, TEST_VIRT_IFNAME);
4501         assertEquals(TEST_VIRT_IFNAME, virtualTetheringRequest.getInterfaceName());
4502         mTethering.startTethering(virtualTetheringRequest, TEST_CALLER_PKG, null);
4503         mLooper.dispatchAll();
4504         assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_VIRT_IFNAME);
4505         mTethering.stopTethering(TETHERING_VIRTUAL);
4506         mLooper.dispatchAll();
4507     }
4508 }
4509