Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 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 | |
markchien | 503be61 | 2020-04-12 21:41:29 +0800 | [diff] [blame] | 17 | package com.android.networkstack.tethering; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 18 | |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 19 | import static android.hardware.usb.UsbManager.USB_CONFIGURED; |
| 20 | import static android.hardware.usb.UsbManager.USB_CONNECTED; |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 21 | import static android.hardware.usb.UsbManager.USB_FUNCTION_NCM; |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 22 | import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 23 | import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; |
| 24 | import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; |
| 25 | import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 26 | import static android.net.RouteInfo.RTN_UNICAST; |
markchien | 9e44cde | 2019-12-25 19:40:32 +0800 | [diff] [blame] | 27 | import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; |
| 28 | import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; |
| 29 | import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER; |
| 30 | import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER; |
Automerger Merge Worker | 06fe92d | 2020-02-28 03:42:44 +0000 | [diff] [blame] | 31 | import static android.net.TetheringManager.TETHERING_ETHERNET; |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 32 | import static android.net.TetheringManager.TETHERING_NCM; |
markchien | 9e44cde | 2019-12-25 19:40:32 +0800 | [diff] [blame] | 33 | import static android.net.TetheringManager.TETHERING_USB; |
| 34 | import static android.net.TetheringManager.TETHERING_WIFI; |
| 35 | import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; |
| 36 | import static android.net.TetheringManager.TETHER_ERROR_UNKNOWN_IFACE; |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 37 | import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED; |
| 38 | import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED; |
| 39 | import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED; |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 40 | import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; |
Treehugger Robot | 86d212b | 2020-03-30 04:23:55 +0000 | [diff] [blame] | 41 | import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH; |
Erik Kline | 2efb827 | 2017-05-31 15:53:53 +0900 | [diff] [blame] | 42 | import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; |
| 43 | import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; |
| 44 | import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; |
markchien | b6eb2c2 | 2018-07-18 14:29:20 +0800 | [diff] [blame] | 45 | import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY; |
| 46 | import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; |
Erik Kline | 2efb827 | 2017-05-31 15:53:53 +0900 | [diff] [blame] | 47 | import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; |
markchien | 0b59507 | 2019-01-08 23:52:21 +0800 | [diff] [blame] | 48 | import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 49 | |
markchien | 503be61 | 2020-04-12 21:41:29 +0800 | [diff] [blame] | 50 | import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; |
Chalard Jean | c0fc276 | 2020-04-17 17:12:44 +0000 | [diff] [blame] | 51 | import static com.android.networkstack.tethering.UpstreamNetworkMonitor.EVENT_ON_CAPABILITIES; |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 52 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 53 | import static org.junit.Assert.assertArrayEquals; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 54 | import static org.junit.Assert.assertEquals; |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 55 | import static org.junit.Assert.assertFalse; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 56 | import static org.junit.Assert.assertTrue; |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 57 | import static org.junit.Assert.fail; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 58 | import static org.mockito.ArgumentMatchers.argThat; |
| 59 | import static org.mockito.ArgumentMatchers.notNull; |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 60 | import static org.mockito.Matchers.anyInt; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 61 | import static org.mockito.Matchers.anyString; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 62 | import static org.mockito.Matchers.eq; |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 63 | import static org.mockito.Mockito.any; |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 64 | import static org.mockito.Mockito.doThrow; |
markchien | b6eb2c2 | 2018-07-18 14:29:20 +0800 | [diff] [blame] | 65 | import static org.mockito.Mockito.mock; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 66 | import static org.mockito.Mockito.never; |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 67 | import static org.mockito.Mockito.reset; |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 68 | import static org.mockito.Mockito.spy; |
| 69 | import static org.mockito.Mockito.timeout; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 70 | import static org.mockito.Mockito.times; |
| 71 | import static org.mockito.Mockito.verify; |
| 72 | import static org.mockito.Mockito.verifyNoMoreInteractions; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 73 | import static org.mockito.Mockito.when; |
| 74 | |
junyulai | caa8100 | 2019-12-11 11:03:01 +0800 | [diff] [blame] | 75 | import android.app.usage.NetworkStatsManager; |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 76 | import android.bluetooth.BluetoothAdapter; |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 77 | import android.content.BroadcastReceiver; |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 78 | import android.content.ContentResolver; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 79 | import android.content.Context; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 80 | import android.content.Intent; |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 81 | import android.content.IntentFilter; |
Erik Kline | f3a08b4 | 2017-06-07 16:33:19 +0900 | [diff] [blame] | 82 | import android.content.pm.ApplicationInfo; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 83 | import android.content.res.Resources; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 84 | import android.hardware.usb.UsbManager; |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 85 | import android.net.ConnectivityManager; |
Automerger Merge Worker | 06fe92d | 2020-02-28 03:42:44 +0000 | [diff] [blame] | 86 | import android.net.EthernetManager; |
| 87 | import android.net.EthernetManager.TetheredInterfaceRequest; |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 88 | import android.net.IIntResultListener; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 89 | import android.net.INetd; |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 90 | import android.net.ITetheringEventCallback; |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 91 | import android.net.InetAddresses; |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 92 | import android.net.InterfaceConfigurationParcel; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 93 | import android.net.IpPrefix; |
| 94 | import android.net.LinkAddress; |
| 95 | import android.net.LinkProperties; |
| 96 | import android.net.MacAddress; |
| 97 | import android.net.Network; |
| 98 | import android.net.NetworkCapabilities; |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 99 | import android.net.NetworkRequest; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 100 | import android.net.RouteInfo; |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 101 | import android.net.TetherStatesParcel; |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 102 | import android.net.TetheredClient; |
markchien | 40898ca | 2020-01-21 13:11:06 +0800 | [diff] [blame] | 103 | import android.net.TetheringCallbackStartedParcel; |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 104 | import android.net.TetheringConfigurationParcel; |
markchien | e8b9d75 | 2020-01-20 19:31:56 +0800 | [diff] [blame] | 105 | import android.net.TetheringRequestParcel; |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 106 | import android.net.dhcp.DhcpServerCallbacks; |
| 107 | import android.net.dhcp.DhcpServingParamsParcel; |
| 108 | import android.net.dhcp.IDhcpServer; |
Lorenzo Colitti | fb19f49 | 2020-02-14 01:06:35 +0900 | [diff] [blame] | 109 | import android.net.ip.IpNeighborMonitor; |
Erik Kline | 7a4ccc6 | 2018-08-27 17:26:47 +0900 | [diff] [blame] | 110 | import android.net.ip.IpServer; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 111 | import android.net.ip.RouterAdvertisementDaemon; |
| 112 | import android.net.util.InterfaceParams; |
| 113 | import android.net.util.NetworkConstants; |
Erik Kline | f4b6e34 | 2017-04-25 19:19:59 +0900 | [diff] [blame] | 114 | import android.net.util.SharedLog; |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 115 | import android.net.wifi.SoftApConfiguration; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 116 | import android.net.wifi.WifiManager; |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 117 | import android.net.wifi.p2p.WifiP2pGroup; |
| 118 | import android.net.wifi.p2p.WifiP2pInfo; |
| 119 | import android.net.wifi.p2p.WifiP2pManager; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 120 | import android.os.Bundle; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 121 | import android.os.Handler; |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 122 | import android.os.Looper; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 123 | import android.os.PersistableBundle; |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 124 | import android.os.RemoteException; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 125 | import android.os.UserHandle; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 126 | import android.os.UserManager; |
markchien | b6eb2c2 | 2018-07-18 14:29:20 +0800 | [diff] [blame] | 127 | import android.os.test.TestLooper; |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 128 | import android.provider.Settings; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 129 | import android.telephony.CarrierConfigManager; |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 130 | import android.telephony.PhoneStateListener; |
| 131 | import android.telephony.TelephonyManager; |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 132 | import android.test.mock.MockContentResolver; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 133 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 134 | import androidx.annotation.NonNull; |
Brett Chabot | 1ae2aa6 | 2019-03-04 14:14:56 -0800 | [diff] [blame] | 135 | import androidx.test.filters.SmallTest; |
| 136 | import androidx.test.runner.AndroidJUnit4; |
| 137 | |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 138 | import com.android.internal.util.ArrayUtils; |
| 139 | import com.android.internal.util.StateMachine; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 140 | import com.android.internal.util.test.BroadcastInterceptingContext; |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 141 | import com.android.internal.util.test.FakeSettingsProvider; |
markchien | faa3728 | 2020-02-06 14:34:08 +0800 | [diff] [blame] | 142 | import com.android.testutils.MiscAssertsKt; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 143 | |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 144 | import org.junit.After; |
Mark Chien | 09ad80f | 2020-04-07 16:17:49 +0000 | [diff] [blame] | 145 | import org.junit.AfterClass; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 146 | import org.junit.Before; |
Mark Chien | 09ad80f | 2020-04-07 16:17:49 +0000 | [diff] [blame] | 147 | import org.junit.BeforeClass; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 148 | import org.junit.Test; |
| 149 | import org.junit.runner.RunWith; |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 150 | import org.mockito.ArgumentCaptor; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 151 | import org.mockito.Mock; |
| 152 | import org.mockito.MockitoAnnotations; |
| 153 | |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 154 | import java.io.FileDescriptor; |
| 155 | import java.io.PrintWriter; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 156 | import java.net.Inet4Address; |
| 157 | import java.net.Inet6Address; |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 158 | import java.util.ArrayList; |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 159 | import java.util.Arrays; |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 160 | import java.util.Collection; |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 161 | import java.util.List; |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 162 | import java.util.Vector; |
| 163 | |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 164 | @RunWith(AndroidJUnit4.class) |
| 165 | @SmallTest |
| 166 | public class TetheringTest { |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 167 | private static final int IFINDEX_OFFSET = 100; |
| 168 | |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 169 | private static final String TEST_MOBILE_IFNAME = "test_rmnet_data0"; |
| 170 | private static final String TEST_XLAT_MOBILE_IFNAME = "v4-test_rmnet_data0"; |
| 171 | private static final String TEST_USB_IFNAME = "test_rndis0"; |
| 172 | private static final String TEST_WLAN_IFNAME = "test_wlan0"; |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 173 | private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0"; |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 174 | private static final String TEST_NCM_IFNAME = "test_ncm0"; |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 175 | private static final String TETHERING_NAME = "Tethering"; |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 176 | private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; |
| 177 | private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app"; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 178 | |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 179 | private static final int DHCPSERVER_START_TIMEOUT_MS = 1000; |
| 180 | |
Erik Kline | f3a08b4 | 2017-06-07 16:33:19 +0900 | [diff] [blame] | 181 | @Mock private ApplicationInfo mApplicationInfo; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 182 | @Mock private Context mContext; |
junyulai | caa8100 | 2019-12-11 11:03:01 +0800 | [diff] [blame] | 183 | @Mock private NetworkStatsManager mStatsManager; |
Erik Kline | 5a7c8a0 | 2017-04-30 19:36:15 +0900 | [diff] [blame] | 184 | @Mock private OffloadHardwareInterface mOffloadHardwareInterface; |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 185 | @Mock private OffloadHardwareInterface.ForwardedStats mForwardedStats; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 186 | @Mock private Resources mResources; |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 187 | @Mock private TelephonyManager mTelephonyManager; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 188 | @Mock private UsbManager mUsbManager; |
| 189 | @Mock private WifiManager mWifiManager; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 190 | @Mock private CarrierConfigManager mCarrierConfigManager; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 191 | @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor; |
| 192 | @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator; |
| 193 | @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon; |
Lorenzo Colitti | fb19f49 | 2020-02-14 01:06:35 +0900 | [diff] [blame] | 194 | @Mock private IpNeighborMonitor mIpNeighborMonitor; |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 195 | @Mock private IDhcpServer mDhcpServer; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 196 | @Mock private INetd mNetd; |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 197 | @Mock private UserManager mUserManager; |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 198 | @Mock private NetworkRequest mNetworkRequest; |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 199 | @Mock private ConnectivityManager mCm; |
Automerger Merge Worker | 06fe92d | 2020-02-28 03:42:44 +0000 | [diff] [blame] | 200 | @Mock private EthernetManager mEm; |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 201 | @Mock private TetheringNotificationUpdater mNotificationUpdater; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 202 | |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 203 | private final MockIpServerDependencies mIpServerDependencies = |
| 204 | spy(new MockIpServerDependencies()); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 205 | private final MockTetheringDependencies mTetheringDependencies = |
| 206 | new MockTetheringDependencies(); |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 207 | |
| 208 | // Like so many Android system APIs, these cannot be mocked because it is marked final. |
| 209 | // We have to use the real versions. |
| 210 | private final PersistableBundle mCarrierConfig = new PersistableBundle(); |
| 211 | private final TestLooper mLooper = new TestLooper(); |
| 212 | |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 213 | private Vector<Intent> mIntents; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 214 | private BroadcastInterceptingContext mServiceContext; |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 215 | private MockContentResolver mContentResolver; |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 216 | private BroadcastReceiver mBroadcastReceiver; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 217 | private Tethering mTethering; |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 218 | private PhoneStateListener mPhoneStateListener; |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 219 | private InterfaceConfigurationParcel mInterfaceConfiguration; |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 220 | private TetheringConfiguration mConfig; |
| 221 | private EntitlementManager mEntitleMgr; |
| 222 | private OffloadController mOffloadCtrl; |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 223 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 224 | private class TestContext extends BroadcastInterceptingContext { |
| 225 | TestContext(Context base) { |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 226 | super(base); |
| 227 | } |
| 228 | |
| 229 | @Override |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 230 | public ApplicationInfo getApplicationInfo() { |
| 231 | return mApplicationInfo; |
| 232 | } |
Erik Kline | f3a08b4 | 2017-06-07 16:33:19 +0900 | [diff] [blame] | 233 | |
| 234 | @Override |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 235 | public ContentResolver getContentResolver() { |
| 236 | return mContentResolver; |
| 237 | } |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 238 | |
| 239 | @Override |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 240 | public String getPackageName() { |
| 241 | return "TetheringTest"; |
| 242 | } |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 243 | |
| 244 | @Override |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 245 | public Resources getResources() { |
| 246 | return mResources; |
| 247 | } |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 248 | |
| 249 | @Override |
| 250 | public Object getSystemService(String name) { |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 251 | if (Context.WIFI_SERVICE.equals(name)) return mWifiManager; |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 252 | if (Context.USB_SERVICE.equals(name)) return mUsbManager; |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 253 | if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 254 | if (Context.USER_SERVICE.equals(name)) return mUserManager; |
junyulai | caa8100 | 2019-12-11 11:03:01 +0800 | [diff] [blame] | 255 | if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 256 | if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; |
Automerger Merge Worker | 06fe92d | 2020-02-28 03:42:44 +0000 | [diff] [blame] | 257 | if (Context.ETHERNET_SERVICE.equals(name)) return mEm; |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 258 | return super.getSystemService(name); |
| 259 | } |
Jayachandran C | 43fa1be | 2019-11-15 09:58:04 -0800 | [diff] [blame] | 260 | |
| 261 | @Override |
| 262 | public String getSystemServiceName(Class<?> serviceClass) { |
| 263 | if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE; |
| 264 | return super.getSystemServiceName(serviceClass); |
| 265 | } |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 266 | } |
| 267 | |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 268 | public class MockIpServerDependencies extends IpServer.Dependencies { |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 269 | @Override |
| 270 | public RouterAdvertisementDaemon getRouterAdvertisementDaemon( |
| 271 | InterfaceParams ifParams) { |
| 272 | return mRouterAdvertisementDaemon; |
| 273 | } |
| 274 | |
| 275 | @Override |
| 276 | public InterfaceParams getInterfaceParams(String ifName) { |
| 277 | assertTrue("Non-mocked interface " + ifName, |
| 278 | ifName.equals(TEST_USB_IFNAME) |
| 279 | || ifName.equals(TEST_WLAN_IFNAME) |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 280 | || ifName.equals(TEST_MOBILE_IFNAME) |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 281 | || ifName.equals(TEST_P2P_IFNAME) |
| 282 | || ifName.equals(TEST_NCM_IFNAME)); |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 283 | final String[] ifaces = new String[] { |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 284 | TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME, TEST_P2P_IFNAME, |
| 285 | TEST_NCM_IFNAME}; |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 286 | return new InterfaceParams(ifName, ArrayUtils.indexOf(ifaces, ifName) + IFINDEX_OFFSET, |
| 287 | MacAddress.ALL_ZEROS_ADDRESS); |
| 288 | } |
| 289 | |
| 290 | @Override |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 291 | public void makeDhcpServer(String ifName, DhcpServingParamsParcel params, |
| 292 | DhcpServerCallbacks cb) { |
| 293 | new Thread(() -> { |
| 294 | try { |
| 295 | cb.onDhcpServerCreated(STATUS_SUCCESS, mDhcpServer); |
| 296 | } catch (RemoteException e) { |
| 297 | fail(e.getMessage()); |
| 298 | } |
| 299 | }).run(); |
| 300 | } |
Lorenzo Colitti | fb19f49 | 2020-02-14 01:06:35 +0900 | [diff] [blame] | 301 | |
| 302 | public IpNeighborMonitor getIpNeighborMonitor(Handler h, SharedLog l, |
| 303 | IpNeighborMonitor.NeighborEventConsumer c) { |
| 304 | return mIpNeighborMonitor; |
| 305 | } |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 306 | } |
| 307 | |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 308 | // MyTetheringConfiguration is used to override static method for testing. |
| 309 | private class MyTetheringConfiguration extends TetheringConfiguration { |
| 310 | MyTetheringConfiguration(Context ctx, SharedLog log, int id) { |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 311 | super(ctx, log, id); |
| 312 | } |
| 313 | |
| 314 | @Override |
markchien | 2dfee02 | 2020-01-13 16:09:42 +0800 | [diff] [blame] | 315 | protected boolean getDeviceConfigBoolean(final String name) { |
| 316 | return false; |
| 317 | } |
| 318 | |
| 319 | @Override |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 320 | protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { |
| 321 | return mResources; |
| 322 | } |
| 323 | } |
| 324 | |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 325 | public class MockTetheringDependencies extends TetheringDependencies { |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 326 | StateMachine mUpstreamNetworkMonitorMasterSM; |
| 327 | ArrayList<IpServer> mIpv6CoordinatorNotifyList; |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 328 | |
| 329 | public void reset() { |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 330 | mUpstreamNetworkMonitorMasterSM = null; |
| 331 | mIpv6CoordinatorNotifyList = null; |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 332 | } |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 333 | |
| 334 | @Override |
| 335 | public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) { |
| 336 | return mOffloadHardwareInterface; |
| 337 | } |
| 338 | |
| 339 | @Override |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 340 | public OffloadController getOffloadController(Handler h, SharedLog log, |
| 341 | OffloadController.Dependencies deps) { |
| 342 | mOffloadCtrl = spy(super.getOffloadController(h, log, deps)); |
| 343 | // Return real object here instead of mock because |
| 344 | // testReportFailCallbackIfOffloadNotSupported depend on real OffloadController object. |
| 345 | return mOffloadCtrl; |
| 346 | } |
| 347 | |
| 348 | @Override |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 349 | public UpstreamNetworkMonitor getUpstreamNetworkMonitor(Context ctx, |
| 350 | StateMachine target, SharedLog log, int what) { |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 351 | mUpstreamNetworkMonitorMasterSM = target; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 352 | return mUpstreamNetworkMonitor; |
| 353 | } |
| 354 | |
| 355 | @Override |
| 356 | public IPv6TetheringCoordinator getIPv6TetheringCoordinator( |
Erik Kline | 7a4ccc6 | 2018-08-27 17:26:47 +0900 | [diff] [blame] | 357 | ArrayList<IpServer> notifyList, SharedLog log) { |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 358 | mIpv6CoordinatorNotifyList = notifyList; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 359 | return mIPv6TetheringCoordinator; |
| 360 | } |
| 361 | |
| 362 | @Override |
Remi NGUYEN VAN | 5db454c | 2019-02-14 18:04:20 +0900 | [diff] [blame] | 363 | public IpServer.Dependencies getIpServerDependencies() { |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 364 | return mIpServerDependencies; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 365 | } |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 366 | |
| 367 | @Override |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 368 | public NetworkRequest getDefaultNetworkRequest() { |
| 369 | return mNetworkRequest; |
| 370 | } |
| 371 | |
| 372 | @Override |
Mark Chien | 47430c0 | 2020-05-08 11:00:42 +0000 | [diff] [blame] | 373 | public EntitlementManager getEntitlementManager(Context ctx, Handler h, SharedLog log, |
| 374 | Runnable callback) { |
| 375 | mEntitleMgr = spy(super.getEntitlementManager(ctx, h, log, callback)); |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 376 | return mEntitleMgr; |
| 377 | } |
| 378 | |
| 379 | @Override |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 380 | public boolean isTetheringSupported() { |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 381 | return true; |
| 382 | } |
markchien | 0b59507 | 2019-01-08 23:52:21 +0800 | [diff] [blame] | 383 | |
| 384 | @Override |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 385 | public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, |
| 386 | int subId) { |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 387 | mConfig = spy(new MyTetheringConfiguration(ctx, log, subId)); |
| 388 | return mConfig; |
markchien | 0b59507 | 2019-01-08 23:52:21 +0800 | [diff] [blame] | 389 | } |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 390 | |
| 391 | @Override |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 392 | public INetd getINetd(Context context) { |
| 393 | return mNetd; |
| 394 | } |
| 395 | |
| 396 | @Override |
| 397 | public Looper getTetheringLooper() { |
| 398 | return mLooper.getLooper(); |
| 399 | } |
| 400 | |
| 401 | @Override |
| 402 | public Context getContext() { |
| 403 | return mServiceContext; |
| 404 | } |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 405 | |
| 406 | @Override |
| 407 | public BluetoothAdapter getBluetoothAdapter() { |
| 408 | // TODO: add test for bluetooth tethering. |
| 409 | return null; |
| 410 | } |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 411 | |
| 412 | @Override |
Paul Hu | 77fa8d6 | 2020-04-16 02:54:37 +0000 | [diff] [blame] | 413 | public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) { |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 414 | return mNotificationUpdater; |
| 415 | } |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 416 | } |
| 417 | |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 418 | private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, |
| 419 | boolean withIPv6, boolean with464xlat) { |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 420 | final LinkProperties prop = new LinkProperties(); |
| 421 | prop.setInterfaceName(TEST_MOBILE_IFNAME); |
| 422 | |
| 423 | if (withIPv4) { |
| 424 | prop.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 425 | InetAddresses.parseNumericAddress("10.0.0.1"), |
| 426 | TEST_MOBILE_IFNAME, RTN_UNICAST)); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 427 | } |
| 428 | |
| 429 | if (withIPv6) { |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 430 | prop.addDnsServer(InetAddresses.parseNumericAddress("2001:db8::2")); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 431 | prop.addLinkAddress( |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 432 | new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::"), |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 433 | NetworkConstants.RFC7421_PREFIX_LENGTH)); |
| 434 | prop.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 435 | InetAddresses.parseNumericAddress("2001:db8::1"), |
| 436 | TEST_MOBILE_IFNAME, RTN_UNICAST)); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 437 | } |
| 438 | |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 439 | if (with464xlat) { |
| 440 | final LinkProperties stackedLink = new LinkProperties(); |
| 441 | stackedLink.setInterfaceName(TEST_XLAT_MOBILE_IFNAME); |
| 442 | stackedLink.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 443 | InetAddresses.parseNumericAddress("192.0.0.1"), |
| 444 | TEST_XLAT_MOBILE_IFNAME, RTN_UNICAST)); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 445 | |
| 446 | prop.addStackedLink(stackedLink); |
| 447 | } |
| 448 | |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 449 | |
| 450 | final NetworkCapabilities capabilities = new NetworkCapabilities() |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 451 | .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 452 | return new UpstreamNetworkState(prop, capabilities, new Network(100)); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 453 | } |
| 454 | |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 455 | private static UpstreamNetworkState buildMobileIPv4UpstreamState() { |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 456 | return buildMobileUpstreamState(true, false, false); |
| 457 | } |
| 458 | |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 459 | private static UpstreamNetworkState buildMobileIPv6UpstreamState() { |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 460 | return buildMobileUpstreamState(false, true, false); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 461 | } |
| 462 | |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 463 | private static UpstreamNetworkState buildMobileDualStackUpstreamState() { |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 464 | return buildMobileUpstreamState(true, true, false); |
| 465 | } |
| 466 | |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 467 | private static UpstreamNetworkState buildMobile464xlatUpstreamState() { |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 468 | return buildMobileUpstreamState(false, true, true); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 469 | } |
| 470 | |
Mark Chien | 09ad80f | 2020-04-07 16:17:49 +0000 | [diff] [blame] | 471 | // See FakeSettingsProvider#clearSettingsProvider() that this needs to be called before and |
| 472 | // after use. |
| 473 | @BeforeClass |
| 474 | public static void setupOnce() { |
| 475 | FakeSettingsProvider.clearSettingsProvider(); |
| 476 | } |
| 477 | |
| 478 | @AfterClass |
| 479 | public static void tearDownOnce() { |
| 480 | FakeSettingsProvider.clearSettingsProvider(); |
| 481 | } |
| 482 | |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 483 | @Before |
| 484 | public void setUp() throws Exception { |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 485 | MockitoAnnotations.initMocks(this); |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 486 | when(mResources.getStringArray(R.array.config_tether_dhcp_range)) |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 487 | .thenReturn(new String[0]); |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 488 | when(mResources.getStringArray(R.array.config_tether_usb_regexs)) |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 489 | .thenReturn(new String[] { "test_rndis\\d" }); |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 490 | when(mResources.getStringArray(R.array.config_tether_wifi_regexs)) |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 491 | .thenReturn(new String[]{ "test_wlan\\d" }); |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 492 | when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 493 | .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" }); |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 494 | when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs)) |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 495 | .thenReturn(new String[0]); |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 496 | when(mResources.getStringArray(R.array.config_tether_ncm_regexs)) |
| 497 | .thenReturn(new String[] { "test_ncm\\d" }); |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 498 | when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]); |
| 499 | when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(false); |
| 500 | when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( |
| 501 | false); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 502 | when(mNetd.interfaceGetList()) |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 503 | .thenReturn(new String[] { |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 504 | TEST_MOBILE_IFNAME, TEST_WLAN_IFNAME, TEST_USB_IFNAME, TEST_P2P_IFNAME, |
| 505 | TEST_NCM_IFNAME}); |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 506 | when(mResources.getString(R.string.config_wifi_tether_enable)).thenReturn(""); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 507 | mInterfaceConfiguration = new InterfaceConfigurationParcel(); |
| 508 | mInterfaceConfiguration.flags = new String[0]; |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 509 | when(mRouterAdvertisementDaemon.start()) |
| 510 | .thenReturn(true); |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 511 | initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */, |
| 512 | 0 /* defaultDisabled */); |
| 513 | when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 514 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 515 | mServiceContext = new TestContext(mContext); |
Erik Kline | 92c4db0 | 2017-05-31 10:21:32 +0900 | [diff] [blame] | 516 | mContentResolver = new MockContentResolver(mServiceContext); |
| 517 | mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 518 | mIntents = new Vector<>(); |
| 519 | mBroadcastReceiver = new BroadcastReceiver() { |
| 520 | @Override |
| 521 | public void onReceive(Context context, Intent intent) { |
| 522 | mIntents.addElement(intent); |
| 523 | } |
| 524 | }; |
| 525 | mServiceContext.registerReceiver(mBroadcastReceiver, |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 526 | new IntentFilter(ACTION_TETHER_STATE_CHANGED)); |
Remi NGUYEN VAN | f5581f8 | 2018-09-28 11:34:15 +0900 | [diff] [blame] | 527 | mTethering = makeTethering(); |
Mark Chien | 674a012 | 2020-03-27 09:37:01 +0000 | [diff] [blame] | 528 | mTethering.startStateMachineUpdaters(); |
junyulai | caa8100 | 2019-12-11 11:03:01 +0800 | [diff] [blame] | 529 | verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any()); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 530 | verify(mNetd).registerUnsolicitedEventListener(any()); |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 531 | final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor = |
| 532 | ArgumentCaptor.forClass(PhoneStateListener.class); |
| 533 | verify(mTelephonyManager).listen(phoneListenerCaptor.capture(), |
| 534 | eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)); |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 535 | verify(mWifiManager).registerSoftApCallback(any(), any()); |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 536 | mPhoneStateListener = phoneListenerCaptor.getValue(); |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 537 | } |
| 538 | |
Remi NGUYEN VAN | f5581f8 | 2018-09-28 11:34:15 +0900 | [diff] [blame] | 539 | private Tethering makeTethering() { |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 540 | mTetheringDependencies.reset(); |
| 541 | return new Tethering(mTetheringDependencies); |
Remi NGUYEN VAN | f5581f8 | 2018-09-28 11:34:15 +0900 | [diff] [blame] | 542 | } |
| 543 | |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 544 | private TetheringRequestParcel createTetheringRequestParcel(final int type) { |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 545 | return createTetheringRequestParcel(type, null, null, false); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 546 | } |
| 547 | |
| 548 | private TetheringRequestParcel createTetheringRequestParcel(final int type, |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 549 | final LinkAddress serverAddr, final LinkAddress clientAddr, final boolean exempt) { |
markchien | e8b9d75 | 2020-01-20 19:31:56 +0800 | [diff] [blame] | 550 | final TetheringRequestParcel request = new TetheringRequestParcel(); |
| 551 | request.tetheringType = type; |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 552 | request.localIPv4Address = serverAddr; |
| 553 | request.staticClientAddress = clientAddr; |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 554 | request.exemptFromEntitlementCheck = exempt; |
markchien | e8b9d75 | 2020-01-20 19:31:56 +0800 | [diff] [blame] | 555 | request.showProvisioningUi = false; |
| 556 | |
| 557 | return request; |
| 558 | } |
| 559 | |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 560 | @After |
| 561 | public void tearDown() { |
| 562 | mServiceContext.unregisterReceiver(mBroadcastReceiver); |
| 563 | } |
| 564 | |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 565 | private void sendWifiApStateChanged(int state) { |
| 566 | final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); |
Erik Kline | 2efb827 | 2017-05-31 15:53:53 +0900 | [diff] [blame] | 567 | intent.putExtra(EXTRA_WIFI_AP_STATE, state); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 568 | mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); |
| 569 | } |
| 570 | |
Erik Kline | 2efb827 | 2017-05-31 15:53:53 +0900 | [diff] [blame] | 571 | private void sendWifiApStateChanged(int state, String ifname, int ipmode) { |
| 572 | final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); |
| 573 | intent.putExtra(EXTRA_WIFI_AP_STATE, state); |
| 574 | intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname); |
| 575 | intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode); |
| 576 | mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); |
| 577 | } |
| 578 | |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 579 | private static final String[] P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST = { |
| 580 | android.Manifest.permission.ACCESS_FINE_LOCATION, |
| 581 | android.Manifest.permission.ACCESS_WIFI_STATE |
| 582 | }; |
| 583 | |
| 584 | private void sendWifiP2pConnectionChanged( |
| 585 | boolean isGroupFormed, boolean isGroupOwner, String ifname) { |
Jimmy Chen | 151384d | 2019-12-03 11:37:09 +0800 | [diff] [blame] | 586 | WifiP2pGroup group = null; |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 587 | WifiP2pInfo p2pInfo = new WifiP2pInfo(); |
| 588 | p2pInfo.groupFormed = isGroupFormed; |
Jimmy Chen | 151384d | 2019-12-03 11:37:09 +0800 | [diff] [blame] | 589 | if (isGroupFormed) { |
| 590 | p2pInfo.isGroupOwner = isGroupOwner; |
| 591 | group = mock(WifiP2pGroup.class); |
| 592 | when(group.isGroupOwner()).thenReturn(isGroupOwner); |
| 593 | when(group.getInterface()).thenReturn(ifname); |
| 594 | } |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 595 | |
David Su | 798a92b | 2020-01-13 12:49:21 -0800 | [diff] [blame] | 596 | final Intent intent = mock(Intent.class); |
| 597 | when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); |
| 598 | when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO)).thenReturn(p2pInfo); |
| 599 | when(intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)).thenReturn(group); |
| 600 | |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 601 | mServiceContext.sendBroadcastAsUserMultiplePermissions(intent, UserHandle.ALL, |
| 602 | P2P_RECEIVER_PERMISSIONS_FOR_BROADCAST); |
| 603 | } |
| 604 | |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 605 | private void sendUsbBroadcast(boolean connected, boolean configured, boolean function, |
| 606 | int type) { |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 607 | final Intent intent = new Intent(UsbManager.ACTION_USB_STATE); |
| 608 | intent.putExtra(USB_CONNECTED, connected); |
| 609 | intent.putExtra(USB_CONFIGURED, configured); |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 610 | if (type == TETHERING_USB) { |
| 611 | intent.putExtra(USB_FUNCTION_RNDIS, function); |
| 612 | } else { |
| 613 | intent.putExtra(USB_FUNCTION_NCM, function); |
| 614 | } |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 615 | mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); |
| 616 | } |
| 617 | |
Erik Kline | 80b7a9f | 2018-02-28 15:01:35 +0900 | [diff] [blame] | 618 | private void sendConfigurationChanged() { |
| 619 | final Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); |
| 620 | mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); |
| 621 | } |
| 622 | |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 623 | private void verifyInterfaceServingModeStarted(String ifname) throws Exception { |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 624 | verify(mNetd, times(1)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); |
| 625 | verify(mNetd, times(1)).tetherInterfaceAdd(ifname); |
| 626 | verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, ifname); |
| 627 | verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(ifname), |
| 628 | anyString(), anyString()); |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 629 | } |
| 630 | |
| 631 | private void verifyTetheringBroadcast(String ifname, String whichExtra) { |
| 632 | // Verify that ifname is in the whichExtra array of the tether state changed broadcast. |
| 633 | final Intent bcast = mIntents.get(0); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 634 | assertEquals(ACTION_TETHER_STATE_CHANGED, bcast.getAction()); |
Erik Kline | 8351faa | 2017-04-17 16:47:23 +0900 | [diff] [blame] | 635 | final ArrayList<String> ifnames = bcast.getStringArrayListExtra(whichExtra); |
| 636 | assertTrue(ifnames.contains(ifname)); |
| 637 | mIntents.remove(bcast); |
| 638 | } |
| 639 | |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 640 | public void failingLocalOnlyHotspotLegacyApBroadcast( |
| 641 | boolean emulateInterfaceStatusChanged) throws Exception { |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 642 | // Emulate externally-visible WifiManager effects, causing the |
| 643 | // per-interface state machine to start up, and telling us that |
| 644 | // hotspot mode is to be started. |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 645 | if (emulateInterfaceStatusChanged) { |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 646 | mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 647 | } |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 648 | sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 649 | mLooper.dispatchAll(); |
| 650 | |
Erik Kline | 7a4ccc6 | 2018-08-27 17:26:47 +0900 | [diff] [blame] | 651 | // If, and only if, Tethering received an interface status changed then |
| 652 | // it creates a IpServer and sends out a broadcast indicating that the |
| 653 | // interface is "available". |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 654 | if (emulateInterfaceStatusChanged) { |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 655 | // There is 1 IpServer state change event: STATE_AVAILABLE |
| 656 | verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 657 | verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); |
Jianpeng Li | a70feec | 2019-05-24 17:40:15 +0900 | [diff] [blame] | 658 | verify(mWifiManager).updateInterfaceIpState( |
| 659 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 660 | } |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 661 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 662 | verifyNoMoreInteractions(mWifiManager); |
| 663 | } |
| 664 | |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 665 | private void prepareNcmTethering() { |
| 666 | // Emulate startTethering(TETHERING_NCM) called |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 667 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_NCM), null); |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 668 | mLooper.dispatchAll(); |
| 669 | verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NCM); |
| 670 | |
| 671 | mTethering.interfaceStatusChanged(TEST_NCM_IFNAME, true); |
| 672 | } |
| 673 | |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 674 | private void prepareUsbTethering(UpstreamNetworkState upstreamState) { |
Erik Kline | 7230290 | 2018-06-14 17:36:40 +0900 | [diff] [blame] | 675 | when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 676 | when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())) |
| 677 | .thenReturn(upstreamState); |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 678 | |
| 679 | // Emulate pressing the USB tethering button in Settings UI. |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 680 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null); |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 681 | mLooper.dispatchAll(); |
Jerry Zhang | 327b809 | 2018-01-09 17:53:04 -0800 | [diff] [blame] | 682 | verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 683 | |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 684 | mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true); |
| 685 | } |
| 686 | |
| 687 | @Test |
| 688 | public void testUsbConfiguredBroadcastStartsTethering() throws Exception { |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 689 | UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 690 | prepareUsbTethering(upstreamState); |
| 691 | |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 692 | // This should produce no activity of any kind. |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 693 | verifyNoMoreInteractions(mNetd); |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 694 | |
| 695 | // Pretend we then receive USB configured broadcast. |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 696 | sendUsbBroadcast(true, true, true, TETHERING_USB); |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 697 | mLooper.dispatchAll(); |
| 698 | // Now we should see the start of tethering mechanics (in this case: |
| 699 | // tetherMatchingInterfaces() which starts by fetching all interfaces). |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 700 | verify(mNetd, times(1)).interfaceGetList(); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 701 | |
| 702 | // UpstreamNetworkMonitor should receive selected upstream |
| 703 | verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any()); |
| 704 | verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network); |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 705 | } |
| 706 | |
| 707 | @Test |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 708 | public void failingLocalOnlyHotspotLegacyApBroadcastWithIfaceStatusChanged() throws Exception { |
| 709 | failingLocalOnlyHotspotLegacyApBroadcast(true); |
| 710 | } |
| 711 | |
| 712 | @Test |
| 713 | public void failingLocalOnlyHotspotLegacyApBroadcastSansIfaceStatusChanged() throws Exception { |
| 714 | failingLocalOnlyHotspotLegacyApBroadcast(false); |
| 715 | } |
| 716 | |
| 717 | public void workingLocalOnlyHotspotEnrichedApBroadcast( |
| 718 | boolean emulateInterfaceStatusChanged) throws Exception { |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 719 | // Emulate externally-visible WifiManager effects, causing the |
| 720 | // per-interface state machine to start up, and telling us that |
| 721 | // hotspot mode is to be started. |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 722 | if (emulateInterfaceStatusChanged) { |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 723 | mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 724 | } |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 725 | sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_LOCAL_ONLY); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 726 | mLooper.dispatchAll(); |
| 727 | |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 728 | verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 729 | verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 730 | verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); |
| 731 | verify(mNetd, times(1)).tetherStartWithConfiguration(any()); |
| 732 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 216af6d | 2017-04-27 20:57:23 +0900 | [diff] [blame] | 733 | verify(mWifiManager).updateInterfaceIpState( |
Jianpeng Li | a70feec | 2019-05-24 17:40:15 +0900 | [diff] [blame] | 734 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); |
| 735 | verify(mWifiManager).updateInterfaceIpState( |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 736 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY); |
Erik Kline | 216af6d | 2017-04-27 20:57:23 +0900 | [diff] [blame] | 737 | verifyNoMoreInteractions(mWifiManager); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 738 | verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); |
markchien | a6c7287 | 2018-11-13 18:34:56 +0900 | [diff] [blame] | 739 | verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 740 | // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY |
| 741 | verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 742 | |
| 743 | // Emulate externally-visible WifiManager effects, when hotspot mode |
| 744 | // is being torn down. |
| 745 | sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 746 | mTethering.interfaceRemoved(TEST_WLAN_IFNAME); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 747 | mLooper.dispatchAll(); |
| 748 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 749 | verify(mNetd, times(1)).tetherApplyDnsInterfaces(); |
| 750 | verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME); |
| 751 | verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); |
| 752 | // interfaceSetCfg() called once for enabling and twice disabling IPv4. |
| 753 | verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); |
| 754 | verify(mNetd, times(1)).tetherStop(); |
| 755 | verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME); |
Jianpeng Li | a70feec | 2019-05-24 17:40:15 +0900 | [diff] [blame] | 756 | verify(mWifiManager, times(3)).updateInterfaceIpState( |
| 757 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 758 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 216af6d | 2017-04-27 20:57:23 +0900 | [diff] [blame] | 759 | verifyNoMoreInteractions(mWifiManager); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 760 | // Asking for the last error after the per-interface state machine |
| 761 | // has been reaped yields an unknown interface error. |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 762 | assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME)); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 763 | } |
| 764 | |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 765 | /** |
Erik Kline | 7a4ccc6 | 2018-08-27 17:26:47 +0900 | [diff] [blame] | 766 | * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator. |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 767 | */ |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 768 | private void sendIPv6TetherUpdates(UpstreamNetworkState upstreamState) { |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 769 | // IPv6TetheringCoordinator must have been notified of downstream |
| 770 | verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream( |
| 771 | argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)), |
Erik Kline | 7a4ccc6 | 2018-08-27 17:26:47 +0900 | [diff] [blame] | 772 | eq(IpServer.STATE_TETHERED)); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 773 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 774 | for (IpServer ipSrv : mTetheringDependencies.mIpv6CoordinatorNotifyList) { |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 775 | UpstreamNetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false); |
Erik Kline | 7a4ccc6 | 2018-08-27 17:26:47 +0900 | [diff] [blame] | 776 | ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, |
paulhu | d9736de | 2019-03-08 16:35:20 +0800 | [diff] [blame] | 777 | upstreamState.linkProperties.isIpv6Provisioned() |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 778 | ? ipv6OnlyState.linkProperties |
| 779 | : null); |
| 780 | } |
| 781 | mLooper.dispatchAll(); |
| 782 | } |
| 783 | |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 784 | private void runUsbTethering(UpstreamNetworkState upstreamState) { |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 785 | prepareUsbTethering(upstreamState); |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 786 | sendUsbBroadcast(true, true, true, TETHERING_USB); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 787 | mLooper.dispatchAll(); |
| 788 | } |
| 789 | |
| 790 | @Test |
| 791 | public void workingMobileUsbTethering_IPv4() throws Exception { |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 792 | UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 793 | runUsbTethering(upstreamState); |
| 794 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 795 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
| 796 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 797 | |
| 798 | sendIPv6TetherUpdates(upstreamState); |
| 799 | verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull()); |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 800 | verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( |
| 801 | any(), any()); |
Remi NGUYEN VAN | f5581f8 | 2018-09-28 11:34:15 +0900 | [diff] [blame] | 802 | } |
| 803 | |
| 804 | @Test |
| 805 | public void workingMobileUsbTethering_IPv4LegacyDhcp() { |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 806 | when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( |
| 807 | true); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 808 | sendConfigurationChanged(); |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 809 | final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); |
Remi NGUYEN VAN | f5581f8 | 2018-09-28 11:34:15 +0900 | [diff] [blame] | 810 | runUsbTethering(upstreamState); |
| 811 | sendIPv6TetherUpdates(upstreamState); |
| 812 | |
Remi NGUYEN VAN | 0e3d0923 | 2018-12-04 12:13:09 +0900 | [diff] [blame] | 813 | verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any()); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 814 | } |
| 815 | |
| 816 | @Test |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 817 | public void workingMobileUsbTethering_IPv6() throws Exception { |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 818 | UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 819 | runUsbTethering(upstreamState); |
| 820 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 821 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
| 822 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 823 | |
| 824 | sendIPv6TetherUpdates(upstreamState); |
| 825 | verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); |
| 826 | verify(mNetd, times(1)).tetherApplyDnsInterfaces(); |
| 827 | } |
| 828 | |
| 829 | @Test |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 830 | public void workingMobileUsbTethering_DualStack() throws Exception { |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 831 | UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 832 | runUsbTethering(upstreamState); |
| 833 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 834 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
| 835 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 836 | verify(mRouterAdvertisementDaemon, times(1)).start(); |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 837 | verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( |
| 838 | any(), any()); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 839 | |
| 840 | sendIPv6TetherUpdates(upstreamState); |
| 841 | verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); |
| 842 | verify(mNetd, times(1)).tetherApplyDnsInterfaces(); |
| 843 | } |
| 844 | |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 845 | @Test |
| 846 | public void workingMobileUsbTethering_MultipleUpstreams() throws Exception { |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 847 | UpstreamNetworkState upstreamState = buildMobile464xlatUpstreamState(); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 848 | runUsbTethering(upstreamState); |
| 849 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 850 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); |
| 851 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 852 | verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( |
| 853 | any(), any()); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 854 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); |
| 855 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 856 | |
| 857 | sendIPv6TetherUpdates(upstreamState); |
| 858 | verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); |
| 859 | verify(mNetd, times(1)).tetherApplyDnsInterfaces(); |
| 860 | } |
| 861 | |
| 862 | @Test |
| 863 | public void workingMobileUsbTethering_v6Then464xlat() throws Exception { |
| 864 | // Setup IPv6 |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 865 | UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 866 | runUsbTethering(upstreamState); |
| 867 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 868 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 869 | verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( |
| 870 | any(), any()); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 871 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 872 | |
| 873 | // Then 464xlat comes up |
| 874 | upstreamState = buildMobile464xlatUpstreamState(); |
| 875 | when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())) |
| 876 | .thenReturn(upstreamState); |
| 877 | |
| 878 | // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES. |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 879 | mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage( |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 880 | Tethering.TetherMasterSM.EVENT_UPSTREAM_CALLBACK, |
| 881 | UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, |
| 882 | 0, |
| 883 | upstreamState); |
| 884 | mLooper.dispatchAll(); |
| 885 | |
| 886 | // Forwarding is added for 464xlat |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 887 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); |
| 888 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 889 | // Forwarding was not re-added for v6 (still times(1)) |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 890 | verify(mNetd, times(1)).tetherAddForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
| 891 | verify(mNetd, times(1)).ipfwdAddInterfaceForward(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); |
Remi NGUYEN VAN | f5581f8 | 2018-09-28 11:34:15 +0900 | [diff] [blame] | 892 | // DHCP not restarted on downstream (still times(1)) |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 893 | verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( |
| 894 | any(), any()); |
Remi NGUYEN VAN | 25a7e4f | 2018-03-09 14:07:18 +0900 | [diff] [blame] | 895 | } |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 896 | |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 897 | @Test |
Erik Kline | 7230290 | 2018-06-14 17:36:40 +0900 | [diff] [blame] | 898 | public void configTetherUpstreamAutomaticIgnoresConfigTetherUpstreamTypes() throws Exception { |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 899 | when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true); |
Erik Kline | 7230290 | 2018-06-14 17:36:40 +0900 | [diff] [blame] | 900 | sendConfigurationChanged(); |
| 901 | |
| 902 | // Setup IPv6 |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 903 | final UpstreamNetworkState upstreamState = buildMobileIPv6UpstreamState(); |
Erik Kline | 7230290 | 2018-06-14 17:36:40 +0900 | [diff] [blame] | 904 | runUsbTethering(upstreamState); |
| 905 | |
| 906 | // UpstreamNetworkMonitor should choose upstream automatically |
| 907 | // (in this specific case: choose the default network). |
| 908 | verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream(); |
| 909 | verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any()); |
| 910 | |
| 911 | verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network); |
| 912 | } |
| 913 | |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 914 | private void runNcmTethering() { |
| 915 | prepareNcmTethering(); |
| 916 | sendUsbBroadcast(true, true, true, TETHERING_NCM); |
| 917 | mLooper.dispatchAll(); |
| 918 | } |
| 919 | |
| 920 | @Test |
| 921 | public void workingNcmTethering() throws Exception { |
| 922 | runNcmTethering(); |
| 923 | |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 924 | verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( |
| 925 | any(), any()); |
Milim Lee | 31ef4c0 | 2019-10-17 05:02:33 +0900 | [diff] [blame] | 926 | } |
| 927 | |
| 928 | @Test |
| 929 | public void workingNcmTethering_LegacyDhcp() { |
| 930 | when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn( |
| 931 | true); |
| 932 | sendConfigurationChanged(); |
| 933 | runNcmTethering(); |
| 934 | |
| 935 | verify(mIpServerDependencies, never()).makeDhcpServer(any(), any(), any()); |
| 936 | } |
| 937 | |
Erik Kline | 7230290 | 2018-06-14 17:36:40 +0900 | [diff] [blame] | 938 | @Test |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 939 | public void workingLocalOnlyHotspotEnrichedApBroadcastWithIfaceChanged() throws Exception { |
| 940 | workingLocalOnlyHotspotEnrichedApBroadcast(true); |
| 941 | } |
| 942 | |
| 943 | @Test |
| 944 | public void workingLocalOnlyHotspotEnrichedApBroadcastSansIfaceChanged() throws Exception { |
| 945 | workingLocalOnlyHotspotEnrichedApBroadcast(false); |
| 946 | } |
| 947 | |
| 948 | // TODO: Test with and without interfaceStatusChanged(). |
| 949 | @Test |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 950 | public void failingWifiTetheringLegacyApBroadcast() throws Exception { |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 951 | when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 952 | |
| 953 | // Emulate pressing the WiFi tethering button. |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 954 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 955 | mLooper.dispatchAll(); |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 956 | verify(mWifiManager, times(1)).startTetheredHotspot(null); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 957 | verifyNoMoreInteractions(mWifiManager); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 958 | verifyNoMoreInteractions(mNetd); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 959 | |
| 960 | // Emulate externally-visible WifiManager effects, causing the |
| 961 | // per-interface state machine to start up, and telling us that |
| 962 | // tethering mode is to be started. |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 963 | mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 964 | sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 965 | mLooper.dispatchAll(); |
| 966 | |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 967 | // There is 1 IpServer state change event: STATE_AVAILABLE |
| 968 | verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 969 | verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); |
Jianpeng Li | a70feec | 2019-05-24 17:40:15 +0900 | [diff] [blame] | 970 | verify(mWifiManager).updateInterfaceIpState( |
| 971 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 972 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 973 | verifyNoMoreInteractions(mWifiManager); |
| 974 | } |
| 975 | |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 976 | // TODO: Test with and without interfaceStatusChanged(). |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 977 | @Test |
| 978 | public void workingWifiTetheringEnrichedApBroadcast() throws Exception { |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 979 | when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 980 | |
| 981 | // Emulate pressing the WiFi tethering button. |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 982 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 983 | mLooper.dispatchAll(); |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 984 | verify(mWifiManager, times(1)).startTetheredHotspot(null); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 985 | verifyNoMoreInteractions(mWifiManager); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 986 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 987 | |
| 988 | // Emulate externally-visible WifiManager effects, causing the |
| 989 | // per-interface state machine to start up, and telling us that |
| 990 | // tethering mode is to be started. |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 991 | mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); |
| 992 | sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); |
Erik Kline | 9e22554 | 2017-06-08 17:48:48 +0900 | [diff] [blame] | 993 | mLooper.dispatchAll(); |
| 994 | |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 995 | verifyInterfaceServingModeStarted(TEST_WLAN_IFNAME); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 996 | verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 997 | verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); |
| 998 | verify(mNetd, times(1)).tetherStartWithConfiguration(any()); |
| 999 | verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME), |
| 1000 | anyString(), anyString()); |
| 1001 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 216af6d | 2017-04-27 20:57:23 +0900 | [diff] [blame] | 1002 | verify(mWifiManager).updateInterfaceIpState( |
Jianpeng Li | a70feec | 2019-05-24 17:40:15 +0900 | [diff] [blame] | 1003 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); |
| 1004 | verify(mWifiManager).updateInterfaceIpState( |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 1005 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); |
Erik Kline | 216af6d | 2017-04-27 20:57:23 +0900 | [diff] [blame] | 1006 | verifyNoMoreInteractions(mWifiManager); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 1007 | verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER); |
markchien | a6c7287 | 2018-11-13 18:34:56 +0900 | [diff] [blame] | 1008 | verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1009 | // In tethering mode, in the default configuration, an explicit request |
| 1010 | // for a mobile network is also made. |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 1011 | verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest(); |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 1012 | // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_TETHERED |
| 1013 | verify(mNotificationUpdater, times(1)).onDownstreamChanged(DOWNSTREAM_NONE); |
| 1014 | verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI)); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1015 | |
| 1016 | ///// |
| 1017 | // We do not currently emulate any upstream being found. |
| 1018 | // |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1019 | // This is why there are no calls to verify mNetd.tetherAddForward() or |
| 1020 | // mNetd.ipfwdAddInterfaceForward(). |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1021 | ///// |
| 1022 | |
| 1023 | // Emulate pressing the WiFi tethering button. |
Erik Kline | c438e30 | 2017-07-04 22:02:49 +0900 | [diff] [blame] | 1024 | mTethering.stopTethering(TETHERING_WIFI); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1025 | mLooper.dispatchAll(); |
Erik Kline | ceb54c6 | 2017-04-18 14:22:25 +0900 | [diff] [blame] | 1026 | verify(mWifiManager, times(1)).stopSoftAp(); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1027 | verifyNoMoreInteractions(mWifiManager); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1028 | verifyNoMoreInteractions(mNetd); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1029 | |
| 1030 | // Emulate externally-visible WifiManager effects, when tethering mode |
| 1031 | // is being torn down. |
| 1032 | sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED); |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 1033 | mTethering.interfaceRemoved(TEST_WLAN_IFNAME); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1034 | mLooper.dispatchAll(); |
| 1035 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1036 | verify(mNetd, times(1)).tetherApplyDnsInterfaces(); |
| 1037 | verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME); |
| 1038 | verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); |
| 1039 | // interfaceSetCfg() called once for enabling and twice for disabling IPv4. |
| 1040 | verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); |
| 1041 | verify(mNetd, times(1)).tetherStop(); |
| 1042 | verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME); |
Jianpeng Li | a70feec | 2019-05-24 17:40:15 +0900 | [diff] [blame] | 1043 | verify(mWifiManager, times(3)).updateInterfaceIpState( |
| 1044 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1045 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 216af6d | 2017-04-27 20:57:23 +0900 | [diff] [blame] | 1046 | verifyNoMoreInteractions(mWifiManager); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1047 | // Asking for the last error after the per-interface state machine |
| 1048 | // has been reaped yields an unknown interface error. |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 1049 | assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_WLAN_IFNAME)); |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1050 | } |
| 1051 | |
Erik Kline | a9cde8b | 2017-06-20 21:18:31 +0900 | [diff] [blame] | 1052 | // TODO: Test with and without interfaceStatusChanged(). |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1053 | @Test |
| 1054 | public void failureEnablingIpForwarding() throws Exception { |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 1055 | when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1056 | doThrow(new RemoteException()).when(mNetd).ipfwdEnableForwarding(TETHERING_NAME); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1057 | |
| 1058 | // Emulate pressing the WiFi tethering button. |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1059 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1060 | mLooper.dispatchAll(); |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 1061 | verify(mWifiManager, times(1)).startTetheredHotspot(null); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1062 | verifyNoMoreInteractions(mWifiManager); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1063 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1064 | |
| 1065 | // Emulate externally-visible WifiManager effects, causing the |
| 1066 | // per-interface state machine to start up, and telling us that |
| 1067 | // tethering mode is to be started. |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 1068 | mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); |
| 1069 | sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1070 | mLooper.dispatchAll(); |
| 1071 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1072 | // We verify get/set called three times here: twice for setup and once during |
| 1073 | // teardown because all events happen over the course of the single |
Erik Kline | 7a4ccc6 | 2018-08-27 17:26:47 +0900 | [diff] [blame] | 1074 | // dispatchAll() above. Note that once the IpServer IPv4 address config |
Erik Kline | 472276a | 2018-05-18 16:09:24 +0900 | [diff] [blame] | 1075 | // code is refactored the two calls during shutdown will revert to one. |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1076 | verify(mNetd, times(3)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName))); |
| 1077 | verify(mNetd, times(1)).tetherInterfaceAdd(TEST_WLAN_IFNAME); |
| 1078 | verify(mNetd, times(1)).networkAddInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); |
| 1079 | verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(TEST_WLAN_IFNAME), |
| 1080 | anyString(), anyString()); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1081 | verify(mWifiManager).updateInterfaceIpState( |
Jianpeng Li | a70feec | 2019-05-24 17:40:15 +0900 | [diff] [blame] | 1082 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_UNSPECIFIED); |
| 1083 | verify(mWifiManager).updateInterfaceIpState( |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 1084 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 1085 | // There are 3 IpServer state change event: |
| 1086 | // STATE_AVAILABLE -> STATE_TETHERED -> STATE_AVAILABLE. |
| 1087 | verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); |
| 1088 | verify(mNotificationUpdater, times(1)).onDownstreamChanged(eq(1 << TETHERING_WIFI)); |
Erik Kline | 465ff3a | 2018-03-09 14:18:02 +0900 | [diff] [blame] | 1089 | verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1090 | // This is called, but will throw. |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1091 | verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1092 | // This never gets called because of the exception thrown above. |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1093 | verify(mNetd, times(0)).tetherStartWithConfiguration(any()); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1094 | // When the master state machine transitions to an error state it tells |
| 1095 | // downstream interfaces, which causes us to tell Wi-Fi about the error |
| 1096 | // so it can take down AP mode. |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1097 | verify(mNetd, times(1)).tetherApplyDnsInterfaces(); |
| 1098 | verify(mNetd, times(1)).tetherInterfaceRemove(TEST_WLAN_IFNAME); |
| 1099 | verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_WLAN_IFNAME); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1100 | verify(mWifiManager).updateInterfaceIpState( |
Remi NGUYEN VAN | a911e84 | 2018-03-15 11:57:14 +0900 | [diff] [blame] | 1101 | TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1102 | |
| 1103 | verifyNoMoreInteractions(mWifiManager); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1104 | verifyNoMoreInteractions(mNetd); |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1105 | } |
| 1106 | |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 1107 | private void runUserRestrictionsChange( |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1108 | boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive, |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1109 | int expectedInteractionsWithShowNotification) throws Exception { |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1110 | final Bundle newRestrictions = new Bundle(); |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1111 | newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow); |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 1112 | final Tethering mockTethering = mock(Tethering.class); |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1113 | when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive); |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 1114 | when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions); |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1115 | |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 1116 | final Tethering.UserRestrictionActionListener ural = |
Paul Hu | f950dc9 | 2020-03-25 12:39:13 +0000 | [diff] [blame] | 1117 | new Tethering.UserRestrictionActionListener( |
| 1118 | mUserManager, mockTethering, mNotificationUpdater); |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 1119 | ural.mDisallowTethering = currentDisallow; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1120 | |
markchien | 1ddfba4 | 2019-11-27 21:20:33 +0800 | [diff] [blame] | 1121 | ural.onUserRestrictionsChanged(); |
| 1122 | |
Paul Hu | f950dc9 | 2020-03-25 12:39:13 +0000 | [diff] [blame] | 1123 | verify(mNotificationUpdater, times(expectedInteractionsWithShowNotification)) |
| 1124 | .notifyTetheringDisabledByRestriction(); |
| 1125 | verify(mockTethering, times(expectedInteractionsWithShowNotification)).untetherAll(); |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1126 | } |
| 1127 | |
| 1128 | @Test |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1129 | public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception { |
| 1130 | final boolean isTetheringActive = false; |
| 1131 | final boolean currDisallow = false; |
| 1132 | final boolean nextDisallow = true; |
| 1133 | final int expectedInteractionsWithShowNotification = 0; |
| 1134 | |
| 1135 | runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, |
| 1136 | expectedInteractionsWithShowNotification); |
| 1137 | } |
| 1138 | |
| 1139 | @Test |
| 1140 | public void testDisallowTetheringWhenTetheringIsActive() throws Exception { |
| 1141 | final boolean isTetheringActive = true; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1142 | final boolean currDisallow = false; |
| 1143 | final boolean nextDisallow = true; |
Paul Hu | f950dc9 | 2020-03-25 12:39:13 +0000 | [diff] [blame] | 1144 | final int expectedInteractionsWithShowNotification = 1; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1145 | |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1146 | runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1147 | expectedInteractionsWithShowNotification); |
| 1148 | } |
| 1149 | |
| 1150 | @Test |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1151 | public void testAllowTetheringWhenTetheringIsNotActive() throws Exception { |
| 1152 | final boolean isTetheringActive = false; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1153 | final boolean currDisallow = true; |
| 1154 | final boolean nextDisallow = false; |
| 1155 | final int expectedInteractionsWithShowNotification = 0; |
| 1156 | |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1157 | runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1158 | expectedInteractionsWithShowNotification); |
| 1159 | } |
| 1160 | |
| 1161 | @Test |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1162 | public void testAllowTetheringWhenTetheringIsActive() throws Exception { |
| 1163 | final boolean isTetheringActive = true; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1164 | final boolean currDisallow = true; |
| 1165 | final boolean nextDisallow = false; |
| 1166 | final int expectedInteractionsWithShowNotification = 0; |
| 1167 | |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1168 | runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1169 | expectedInteractionsWithShowNotification); |
| 1170 | } |
| 1171 | |
| 1172 | @Test |
| 1173 | public void testDisallowTetheringUnchanged() throws Exception { |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1174 | final boolean isTetheringActive = true; |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1175 | final int expectedInteractionsWithShowNotification = 0; |
| 1176 | boolean currDisallow = true; |
| 1177 | boolean nextDisallow = true; |
| 1178 | |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1179 | runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1180 | expectedInteractionsWithShowNotification); |
| 1181 | |
| 1182 | currDisallow = false; |
| 1183 | nextDisallow = false; |
| 1184 | |
Paul Hu | 4089bb1 | 2020-04-23 09:07:00 +0000 | [diff] [blame] | 1185 | runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive, |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1186 | expectedInteractionsWithShowNotification); |
| 1187 | } |
| 1188 | |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1189 | private class TestTetheringEventCallback extends ITetheringEventCallback.Stub { |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1190 | private final ArrayList<Network> mActualUpstreams = new ArrayList<>(); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1191 | private final ArrayList<TetheringConfigurationParcel> mTetheringConfigs = |
| 1192 | new ArrayList<>(); |
| 1193 | private final ArrayList<TetherStatesParcel> mTetherStates = new ArrayList<>(); |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1194 | private final ArrayList<Integer> mOffloadStatus = new ArrayList<>(); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1195 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1196 | // This function will remove the recorded callbacks, so it must be called once for |
| 1197 | // each callback. If this is called after multiple callback, the order matters. |
| 1198 | // onCallbackCreated counts as the first call to expectUpstreamChanged with |
| 1199 | // @see onCallbackCreated. |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1200 | public void expectUpstreamChanged(Network... networks) { |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1201 | if (networks == null) { |
| 1202 | assertNoUpstreamChangeCallback(); |
| 1203 | return; |
| 1204 | } |
| 1205 | |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1206 | final ArrayList<Network> expectedUpstreams = |
| 1207 | new ArrayList<Network>(Arrays.asList(networks)); |
| 1208 | for (Network upstream : expectedUpstreams) { |
| 1209 | // throws OOB if no expectations |
| 1210 | assertEquals(mActualUpstreams.remove(0), upstream); |
| 1211 | } |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1212 | assertNoUpstreamChangeCallback(); |
| 1213 | } |
| 1214 | |
| 1215 | // This function will remove the recorded callbacks, so it must be called once |
| 1216 | // for each callback. If this is called after multiple callback, the order matters. |
| 1217 | // onCallbackCreated counts as the first call to onConfigurationChanged with |
| 1218 | // @see onCallbackCreated. |
| 1219 | public void expectConfigurationChanged(TetheringConfigurationParcel... tetherConfigs) { |
| 1220 | final ArrayList<TetheringConfigurationParcel> expectedTetherConfig = |
| 1221 | new ArrayList<TetheringConfigurationParcel>(Arrays.asList(tetherConfigs)); |
| 1222 | for (TetheringConfigurationParcel config : expectedTetherConfig) { |
| 1223 | // throws OOB if no expectations |
| 1224 | final TetheringConfigurationParcel actualConfig = mTetheringConfigs.remove(0); |
| 1225 | assertTetherConfigParcelEqual(actualConfig, config); |
| 1226 | } |
| 1227 | assertNoConfigChangeCallback(); |
| 1228 | } |
| 1229 | |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1230 | public void expectOffloadStatusChanged(final int expectedStatus) { |
| 1231 | assertOffloadStatusChangedCallback(); |
| 1232 | assertEquals(mOffloadStatus.remove(0), new Integer(expectedStatus)); |
| 1233 | } |
| 1234 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1235 | public TetherStatesParcel pollTetherStatesChanged() { |
| 1236 | assertStateChangeCallback(); |
| 1237 | return mTetherStates.remove(0); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1238 | } |
| 1239 | |
| 1240 | @Override |
| 1241 | public void onUpstreamChanged(Network network) { |
| 1242 | mActualUpstreams.add(network); |
| 1243 | } |
| 1244 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1245 | @Override |
| 1246 | public void onConfigurationChanged(TetheringConfigurationParcel config) { |
| 1247 | mTetheringConfigs.add(config); |
| 1248 | } |
| 1249 | |
| 1250 | @Override |
| 1251 | public void onTetherStatesChanged(TetherStatesParcel states) { |
| 1252 | mTetherStates.add(states); |
| 1253 | } |
| 1254 | |
| 1255 | @Override |
Remi NGUYEN VAN | 43b0e5c | 2020-02-13 09:16:19 +0900 | [diff] [blame] | 1256 | public void onTetherClientsChanged(List<TetheredClient> clients) { |
| 1257 | // TODO: check this |
| 1258 | } |
| 1259 | |
| 1260 | @Override |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1261 | public void onOffloadStatusChanged(final int status) { |
| 1262 | mOffloadStatus.add(status); |
| 1263 | } |
| 1264 | |
| 1265 | @Override |
markchien | 40898ca | 2020-01-21 13:11:06 +0800 | [diff] [blame] | 1266 | public void onCallbackStarted(TetheringCallbackStartedParcel parcel) { |
| 1267 | mActualUpstreams.add(parcel.upstreamNetwork); |
| 1268 | mTetheringConfigs.add(parcel.config); |
| 1269 | mTetherStates.add(parcel.states); |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1270 | mOffloadStatus.add(parcel.offloadStatus); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1271 | } |
| 1272 | |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1273 | @Override |
| 1274 | public void onCallbackStopped(int errorCode) { } |
| 1275 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1276 | public void assertNoUpstreamChangeCallback() { |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1277 | assertTrue(mActualUpstreams.isEmpty()); |
| 1278 | } |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1279 | |
| 1280 | public void assertNoConfigChangeCallback() { |
| 1281 | assertTrue(mTetheringConfigs.isEmpty()); |
| 1282 | } |
| 1283 | |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1284 | public void assertNoStateChangeCallback() { |
| 1285 | assertTrue(mTetherStates.isEmpty()); |
| 1286 | } |
| 1287 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1288 | public void assertStateChangeCallback() { |
| 1289 | assertFalse(mTetherStates.isEmpty()); |
| 1290 | } |
| 1291 | |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1292 | public void assertOffloadStatusChangedCallback() { |
| 1293 | assertFalse(mOffloadStatus.isEmpty()); |
| 1294 | } |
| 1295 | |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1296 | public void assertNoCallback() { |
| 1297 | assertNoUpstreamChangeCallback(); |
| 1298 | assertNoConfigChangeCallback(); |
| 1299 | assertNoStateChangeCallback(); |
| 1300 | } |
| 1301 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1302 | private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual, |
| 1303 | @NonNull TetheringConfigurationParcel expect) { |
| 1304 | assertEquals(actual.subId, expect.subId); |
| 1305 | assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs); |
| 1306 | assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs); |
| 1307 | assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs); |
| 1308 | assertEquals(actual.isDunRequired, expect.isDunRequired); |
| 1309 | assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically); |
| 1310 | assertArrayEquals(actual.preferredUpstreamIfaceTypes, |
| 1311 | expect.preferredUpstreamIfaceTypes); |
| 1312 | assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges); |
| 1313 | assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS); |
| 1314 | assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer); |
| 1315 | assertArrayEquals(actual.provisioningApp, expect.provisioningApp); |
| 1316 | assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi); |
| 1317 | assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod); |
| 1318 | } |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1319 | } |
| 1320 | |
markchien | faa3728 | 2020-02-06 14:34:08 +0800 | [diff] [blame] | 1321 | private void assertTetherStatesNotNullButEmpty(final TetherStatesParcel parcel) { |
| 1322 | assertFalse(parcel == null); |
| 1323 | assertEquals(0, parcel.availableList.length); |
| 1324 | assertEquals(0, parcel.tetheredList.length); |
| 1325 | assertEquals(0, parcel.localOnlyList.length); |
| 1326 | assertEquals(0, parcel.erroredIfaceList.length); |
| 1327 | assertEquals(0, parcel.lastErrorList.length); |
| 1328 | MiscAssertsKt.assertFieldCountEquals(5, TetherStatesParcel.class); |
| 1329 | } |
| 1330 | |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1331 | @Test |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1332 | public void testRegisterTetheringEventCallback() throws Exception { |
| 1333 | TestTetheringEventCallback callback = new TestTetheringEventCallback(); |
| 1334 | TestTetheringEventCallback callback2 = new TestTetheringEventCallback(); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1335 | |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1336 | // 1. Register one callback before running any tethering. |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1337 | mTethering.registerTetheringEventCallback(callback); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1338 | mLooper.dispatchAll(); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1339 | callback.expectUpstreamChanged(new Network[] {null}); |
| 1340 | callback.expectConfigurationChanged( |
| 1341 | mTethering.getTetheringConfiguration().toStableParcelable()); |
| 1342 | TetherStatesParcel tetherState = callback.pollTetherStatesChanged(); |
markchien | faa3728 | 2020-02-06 14:34:08 +0800 | [diff] [blame] | 1343 | assertTetherStatesNotNullButEmpty(tetherState); |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1344 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1345 | // 2. Enable wifi tethering. |
markchien | b0aca96 | 2019-12-05 16:21:17 +0800 | [diff] [blame] | 1346 | UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1347 | when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState); |
| 1348 | when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())) |
| 1349 | .thenReturn(upstreamState); |
lesl | 6b7551a | 2019-12-13 10:56:35 +0800 | [diff] [blame] | 1350 | when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1351 | mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1352 | mLooper.dispatchAll(); |
| 1353 | tetherState = callback.pollTetherStatesChanged(); |
| 1354 | assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME}); |
| 1355 | |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1356 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_WIFI), null); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1357 | sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); |
| 1358 | mLooper.dispatchAll(); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1359 | tetherState = callback.pollTetherStatesChanged(); |
| 1360 | assertArrayEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME}); |
| 1361 | callback.expectUpstreamChanged(upstreamState.network); |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1362 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1363 | |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1364 | // 3. Register second callback. |
| 1365 | mTethering.registerTetheringEventCallback(callback2); |
| 1366 | mLooper.dispatchAll(); |
| 1367 | callback2.expectUpstreamChanged(upstreamState.network); |
| 1368 | callback2.expectConfigurationChanged( |
| 1369 | mTethering.getTetheringConfiguration().toStableParcelable()); |
| 1370 | tetherState = callback2.pollTetherStatesChanged(); |
| 1371 | assertEquals(tetherState.tetheredList, new String[] {TEST_WLAN_IFNAME}); |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1372 | callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STARTED); |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1373 | |
| 1374 | // 4. Unregister first callback and disable wifi tethering |
| 1375 | mTethering.unregisterTetheringEventCallback(callback); |
| 1376 | mLooper.dispatchAll(); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1377 | mTethering.stopTethering(TETHERING_WIFI); |
| 1378 | sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED); |
| 1379 | mLooper.dispatchAll(); |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1380 | tetherState = callback2.pollTetherStatesChanged(); |
markchien | 0f63ca6 | 2019-09-30 14:40:57 +0800 | [diff] [blame] | 1381 | assertArrayEquals(tetherState.availableList, new String[] {TEST_WLAN_IFNAME}); |
| 1382 | mLooper.dispatchAll(); |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1383 | callback2.expectUpstreamChanged(new Network[] {null}); |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1384 | callback2.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); |
markchien | ae8aa64 | 2019-12-16 20:15:20 +0800 | [diff] [blame] | 1385 | callback.assertNoCallback(); |
markchien | 26299ed | 2019-02-27 14:56:11 +0800 | [diff] [blame] | 1386 | } |
Alexandru-Andrei Rotaru | fa6d5c5 | 2017-07-18 16:49:22 +0100 | [diff] [blame] | 1387 | |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 1388 | @Test |
Automerger Merge Worker | c22ab7b | 2020-03-09 04:07:07 +0000 | [diff] [blame] | 1389 | public void testReportFailCallbackIfOffloadNotSupported() throws Exception { |
| 1390 | final UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState(); |
| 1391 | TestTetheringEventCallback callback = new TestTetheringEventCallback(); |
| 1392 | mTethering.registerTetheringEventCallback(callback); |
| 1393 | mLooper.dispatchAll(); |
| 1394 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); |
| 1395 | |
| 1396 | // 1. Offload fail if no OffloadConfig. |
| 1397 | initOffloadConfiguration(false /* offloadConfig */, true /* offloadControl */, |
| 1398 | 0 /* defaultDisabled */); |
| 1399 | runUsbTethering(upstreamState); |
| 1400 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); |
| 1401 | runStopUSBTethering(); |
| 1402 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); |
| 1403 | reset(mUsbManager); |
| 1404 | // 2. Offload fail if no OffloadControl. |
| 1405 | initOffloadConfiguration(true /* offloadConfig */, false /* offloadControl */, |
| 1406 | 0 /* defaultDisabled */); |
| 1407 | runUsbTethering(upstreamState); |
| 1408 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); |
| 1409 | runStopUSBTethering(); |
| 1410 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); |
| 1411 | reset(mUsbManager); |
| 1412 | // 3. Offload fail if disabled by settings. |
| 1413 | initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */, |
| 1414 | 1 /* defaultDisabled */); |
| 1415 | runUsbTethering(upstreamState); |
| 1416 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED); |
| 1417 | runStopUSBTethering(); |
| 1418 | callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED); |
| 1419 | } |
| 1420 | |
| 1421 | private void runStopUSBTethering() { |
| 1422 | mTethering.stopTethering(TETHERING_USB); |
| 1423 | mLooper.dispatchAll(); |
| 1424 | mTethering.interfaceRemoved(TEST_USB_IFNAME); |
| 1425 | mLooper.dispatchAll(); |
| 1426 | } |
| 1427 | |
| 1428 | private void initOffloadConfiguration(final boolean offloadConfig, |
| 1429 | final boolean offloadControl, final int defaultDisabled) { |
| 1430 | when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig); |
| 1431 | when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControl); |
| 1432 | when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn( |
| 1433 | defaultDisabled); |
| 1434 | } |
| 1435 | |
| 1436 | @Test |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 1437 | public void testMultiSimAware() throws Exception { |
| 1438 | final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration(); |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 1439 | assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.activeDataSubId); |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 1440 | |
| 1441 | final int fakeSubId = 1234; |
| 1442 | mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); |
| 1443 | final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); |
markchien | 986750b | 2019-12-06 15:24:53 +0800 | [diff] [blame] | 1444 | assertEquals(fakeSubId, newConfig.activeDataSubId); |
Paul Hu | 274cc1c | 2020-03-25 06:22:43 +0000 | [diff] [blame] | 1445 | verify(mNotificationUpdater, times(1)).onActiveDataSubscriptionIdChanged(eq(fakeSubId)); |
markchien | 04bdf87 | 2019-06-17 21:05:34 +0800 | [diff] [blame] | 1446 | } |
| 1447 | |
Automerger Merge Worker | 06fe92d | 2020-02-28 03:42:44 +0000 | [diff] [blame] | 1448 | @Test |
| 1449 | public void testNoDuplicatedEthernetRequest() throws Exception { |
| 1450 | final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class); |
| 1451 | when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1452 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null); |
Automerger Merge Worker | 06fe92d | 2020-02-28 03:42:44 +0000 | [diff] [blame] | 1453 | mLooper.dispatchAll(); |
| 1454 | verify(mEm, times(1)).requestTetheredInterface(any(), any()); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1455 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_ETHERNET), null); |
Automerger Merge Worker | 06fe92d | 2020-02-28 03:42:44 +0000 | [diff] [blame] | 1456 | mLooper.dispatchAll(); |
| 1457 | verifyNoMoreInteractions(mEm); |
| 1458 | mTethering.stopTethering(TETHERING_ETHERNET); |
| 1459 | mLooper.dispatchAll(); |
| 1460 | verify(mockRequest, times(1)).release(); |
| 1461 | mTethering.stopTethering(TETHERING_ETHERNET); |
| 1462 | mLooper.dispatchAll(); |
| 1463 | verifyNoMoreInteractions(mEm); |
| 1464 | } |
| 1465 | |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1466 | private void workingWifiP2pGroupOwner( |
| 1467 | boolean emulateInterfaceStatusChanged) throws Exception { |
| 1468 | if (emulateInterfaceStatusChanged) { |
| 1469 | mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); |
| 1470 | } |
| 1471 | sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); |
| 1472 | mLooper.dispatchAll(); |
| 1473 | |
| 1474 | verifyInterfaceServingModeStarted(TEST_P2P_IFNAME); |
| 1475 | verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_AVAILABLE_TETHER); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1476 | verify(mNetd, times(1)).ipfwdEnableForwarding(TETHERING_NAME); |
| 1477 | verify(mNetd, times(1)).tetherStartWithConfiguration(any()); |
| 1478 | verifyNoMoreInteractions(mNetd); |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1479 | verifyTetheringBroadcast(TEST_P2P_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); |
| 1480 | verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); |
Automerger Merge Worker | 2d7bacc | 2020-03-09 08:54:00 +0000 | [diff] [blame] | 1481 | // There are 2 IpServer state change events: STATE_AVAILABLE -> STATE_LOCAL_ONLY |
| 1482 | verify(mNotificationUpdater, times(2)).onDownstreamChanged(DOWNSTREAM_NONE); |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1483 | |
| 1484 | assertEquals(TETHER_ERROR_NO_ERROR, mTethering.getLastTetherError(TEST_P2P_IFNAME)); |
| 1485 | |
| 1486 | // Emulate externally-visible WifiP2pManager effects, when wifi p2p group |
| 1487 | // is being removed. |
| 1488 | sendWifiP2pConnectionChanged(false, true, TEST_P2P_IFNAME); |
| 1489 | mTethering.interfaceRemoved(TEST_P2P_IFNAME); |
| 1490 | mLooper.dispatchAll(); |
| 1491 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1492 | verify(mNetd, times(1)).tetherApplyDnsInterfaces(); |
| 1493 | verify(mNetd, times(1)).tetherInterfaceRemove(TEST_P2P_IFNAME); |
| 1494 | verify(mNetd, times(1)).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); |
| 1495 | // interfaceSetCfg() called once for enabling and twice for disabling IPv4. |
| 1496 | verify(mNetd, times(3)).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); |
| 1497 | verify(mNetd, times(1)).tetherStop(); |
| 1498 | verify(mNetd, times(1)).ipfwdDisableForwarding(TETHERING_NAME); |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1499 | verify(mUpstreamNetworkMonitor, never()).getCurrentPreferredUpstream(); |
| 1500 | verify(mUpstreamNetworkMonitor, never()).selectPreferredUpstreamType(any()); |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1501 | verifyNoMoreInteractions(mNetd); |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1502 | // Asking for the last error after the per-interface state machine |
| 1503 | // has been reaped yields an unknown interface error. |
| 1504 | assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME)); |
| 1505 | } |
| 1506 | |
| 1507 | private void workingWifiP2pGroupClient( |
| 1508 | boolean emulateInterfaceStatusChanged) throws Exception { |
| 1509 | if (emulateInterfaceStatusChanged) { |
| 1510 | mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); |
| 1511 | } |
| 1512 | sendWifiP2pConnectionChanged(true, false, TEST_P2P_IFNAME); |
| 1513 | mLooper.dispatchAll(); |
| 1514 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1515 | verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); |
| 1516 | verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME); |
| 1517 | verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); |
| 1518 | verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME); |
| 1519 | verify(mNetd, never()).tetherStartWithConfiguration(any()); |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1520 | |
| 1521 | // Emulate externally-visible WifiP2pManager effects, when wifi p2p group |
| 1522 | // is being removed. |
| 1523 | sendWifiP2pConnectionChanged(false, false, TEST_P2P_IFNAME); |
| 1524 | mTethering.interfaceRemoved(TEST_P2P_IFNAME); |
| 1525 | mLooper.dispatchAll(); |
| 1526 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1527 | verify(mNetd, never()).tetherApplyDnsInterfaces(); |
| 1528 | verify(mNetd, never()).tetherInterfaceRemove(TEST_P2P_IFNAME); |
| 1529 | verify(mNetd, never()).networkRemoveInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); |
| 1530 | verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); |
| 1531 | verify(mNetd, never()).tetherStop(); |
| 1532 | verify(mNetd, never()).ipfwdDisableForwarding(TETHERING_NAME); |
| 1533 | verifyNoMoreInteractions(mNetd); |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1534 | // Asking for the last error after the per-interface state machine |
| 1535 | // has been reaped yields an unknown interface error. |
| 1536 | assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME)); |
| 1537 | } |
| 1538 | |
| 1539 | @Test |
| 1540 | public void workingWifiP2pGroupOwnerWithIfaceChanged() throws Exception { |
| 1541 | workingWifiP2pGroupOwner(true); |
| 1542 | } |
| 1543 | |
| 1544 | @Test |
| 1545 | public void workingWifiP2pGroupOwnerSansIfaceChanged() throws Exception { |
| 1546 | workingWifiP2pGroupOwner(false); |
| 1547 | } |
| 1548 | |
| 1549 | private void workingWifiP2pGroupOwnerLegacyMode( |
| 1550 | boolean emulateInterfaceStatusChanged) throws Exception { |
| 1551 | // change to legacy mode and update tethering information by chaning SIM |
markchien | da4519a | 2020-01-14 12:46:53 +0800 | [diff] [blame] | 1552 | when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs)) |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1553 | .thenReturn(new String[]{}); |
| 1554 | final int fakeSubId = 1234; |
| 1555 | mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); |
| 1556 | |
| 1557 | if (emulateInterfaceStatusChanged) { |
| 1558 | mTethering.interfaceStatusChanged(TEST_P2P_IFNAME, true); |
| 1559 | } |
| 1560 | sendWifiP2pConnectionChanged(true, true, TEST_P2P_IFNAME); |
| 1561 | mLooper.dispatchAll(); |
| 1562 | |
markchien | a9d9ef8 | 2020-01-07 14:43:17 +0800 | [diff] [blame] | 1563 | verify(mNetd, never()).interfaceSetCfg(any(InterfaceConfigurationParcel.class)); |
| 1564 | verify(mNetd, never()).tetherInterfaceAdd(TEST_P2P_IFNAME); |
| 1565 | verify(mNetd, never()).networkAddInterface(INetd.LOCAL_NET_ID, TEST_P2P_IFNAME); |
| 1566 | verify(mNetd, never()).ipfwdEnableForwarding(TETHERING_NAME); |
| 1567 | verify(mNetd, never()).tetherStartWithConfiguration(any()); |
Jimmy Chen | bcd86d0 | 2019-07-15 18:03:23 +0800 | [diff] [blame] | 1568 | assertEquals(TETHER_ERROR_UNKNOWN_IFACE, mTethering.getLastTetherError(TEST_P2P_IFNAME)); |
| 1569 | } |
| 1570 | @Test |
| 1571 | public void workingWifiP2pGroupOwnerLegacyModeWithIfaceChanged() throws Exception { |
| 1572 | workingWifiP2pGroupOwnerLegacyMode(true); |
| 1573 | } |
| 1574 | |
| 1575 | @Test |
| 1576 | public void workingWifiP2pGroupOwnerLegacyModeSansIfaceChanged() throws Exception { |
| 1577 | workingWifiP2pGroupOwnerLegacyMode(false); |
| 1578 | } |
| 1579 | |
| 1580 | @Test |
| 1581 | public void workingWifiP2pGroupClientWithIfaceChanged() throws Exception { |
| 1582 | workingWifiP2pGroupClient(true); |
| 1583 | } |
| 1584 | |
| 1585 | @Test |
| 1586 | public void workingWifiP2pGroupClientSansIfaceChanged() throws Exception { |
| 1587 | workingWifiP2pGroupClient(false); |
| 1588 | } |
| 1589 | |
markchien | 3fe660b | 2019-12-05 12:04:59 +0800 | [diff] [blame] | 1590 | private void setDataSaverEnabled(boolean enabled) { |
| 1591 | final Intent intent = new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED); |
| 1592 | mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL); |
| 1593 | |
| 1594 | final int status = enabled ? RESTRICT_BACKGROUND_STATUS_ENABLED |
| 1595 | : RESTRICT_BACKGROUND_STATUS_DISABLED; |
| 1596 | when(mCm.getRestrictBackgroundStatus()).thenReturn(status); |
| 1597 | mLooper.dispatchAll(); |
| 1598 | } |
| 1599 | |
| 1600 | @Test |
| 1601 | public void testDataSaverChanged() { |
| 1602 | // Start Tethering. |
| 1603 | final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); |
| 1604 | runUsbTethering(upstreamState); |
| 1605 | assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); |
| 1606 | // Data saver is ON. |
| 1607 | setDataSaverEnabled(true); |
| 1608 | // Verify that tethering should be disabled. |
| 1609 | verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); |
| 1610 | mTethering.interfaceRemoved(TEST_USB_IFNAME); |
| 1611 | mLooper.dispatchAll(); |
| 1612 | assertEquals(mTethering.getTetheredIfaces(), new String[0]); |
| 1613 | reset(mUsbManager); |
| 1614 | |
| 1615 | runUsbTethering(upstreamState); |
| 1616 | // Verify that user can start tethering again without turning OFF data saver. |
| 1617 | assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); |
| 1618 | |
| 1619 | // If data saver is keep ON with change event, tethering should not be OFF this time. |
| 1620 | setDataSaverEnabled(true); |
| 1621 | verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); |
| 1622 | assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); |
| 1623 | |
| 1624 | // If data saver is turned OFF, it should not change tethering. |
| 1625 | setDataSaverEnabled(false); |
| 1626 | verify(mUsbManager, times(0)).setCurrentFunctions(UsbManager.FUNCTION_NONE); |
| 1627 | assertContains(Arrays.asList(mTethering.getTetheredIfaces()), TEST_USB_IFNAME); |
| 1628 | } |
| 1629 | |
| 1630 | private static <T> void assertContains(Collection<T> collection, T element) { |
| 1631 | assertTrue(element + " not found in " + collection, collection.contains(element)); |
| 1632 | } |
| 1633 | |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1634 | private class ResultListener extends IIntResultListener.Stub { |
| 1635 | private final int mExpectedResult; |
| 1636 | private boolean mHasResult = false; |
| 1637 | ResultListener(final int expectedResult) { |
| 1638 | mExpectedResult = expectedResult; |
| 1639 | } |
| 1640 | |
| 1641 | @Override |
| 1642 | public void onResult(final int resultCode) { |
| 1643 | mHasResult = true; |
| 1644 | if (resultCode != mExpectedResult) { |
| 1645 | fail("expected result: " + mExpectedResult + " but actual result: " + resultCode); |
| 1646 | } |
| 1647 | } |
| 1648 | |
| 1649 | public void assertHasResult() { |
| 1650 | if (!mHasResult) fail("No callback result"); |
| 1651 | } |
| 1652 | } |
| 1653 | |
| 1654 | @Test |
| 1655 | public void testMultipleStartTethering() throws Exception { |
| 1656 | final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24"); |
| 1657 | final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24"); |
| 1658 | final String serverAddr = "192.168.20.1"; |
| 1659 | final ResultListener firstResult = new ResultListener(TETHER_ERROR_NO_ERROR); |
| 1660 | final ResultListener secondResult = new ResultListener(TETHER_ERROR_NO_ERROR); |
| 1661 | final ResultListener thirdResult = new ResultListener(TETHER_ERROR_NO_ERROR); |
| 1662 | |
| 1663 | // Enable USB tethering and check that Tethering starts USB. |
| 1664 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 1665 | null, null, false), firstResult); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1666 | mLooper.dispatchAll(); |
| 1667 | firstResult.assertHasResult(); |
| 1668 | verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); |
| 1669 | verifyNoMoreInteractions(mUsbManager); |
| 1670 | |
| 1671 | // Enable USB tethering again with the same request and expect no change to USB. |
| 1672 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 1673 | null, null, false), secondResult); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1674 | mLooper.dispatchAll(); |
| 1675 | secondResult.assertHasResult(); |
| 1676 | verify(mUsbManager, never()).setCurrentFunctions(UsbManager.FUNCTION_NONE); |
| 1677 | reset(mUsbManager); |
| 1678 | |
| 1679 | // Enable USB tethering with a different request and expect that USB is stopped and |
| 1680 | // started. |
| 1681 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 1682 | serverLinkAddr, clientLinkAddr, false), thirdResult); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1683 | mLooper.dispatchAll(); |
| 1684 | thirdResult.assertHasResult(); |
| 1685 | verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_NONE); |
| 1686 | verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); |
| 1687 | |
| 1688 | // Expect that when USB comes up, the DHCP server is configured with the requested address. |
| 1689 | mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true); |
| 1690 | sendUsbBroadcast(true, true, true, TETHERING_USB); |
| 1691 | mLooper.dispatchAll(); |
| 1692 | verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( |
| 1693 | any(), any()); |
| 1694 | verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); |
| 1695 | } |
| 1696 | |
| 1697 | @Test |
Treehugger Robot | 86d212b | 2020-03-30 04:23:55 +0000 | [diff] [blame] | 1698 | public void testRequestStaticIp() throws Exception { |
| 1699 | final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24"); |
| 1700 | final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24"); |
| 1701 | final String serverAddr = "192.168.0.123"; |
| 1702 | final int clientAddrParceled = 0xc0a8002a; |
| 1703 | final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor = |
| 1704 | ArgumentCaptor.forClass(DhcpServingParamsParcel.class); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1705 | mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB, |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 1706 | serverLinkAddr, clientLinkAddr, false), null); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1707 | mLooper.dispatchAll(); |
| 1708 | verify(mUsbManager, times(1)).setCurrentFunctions(UsbManager.FUNCTION_RNDIS); |
| 1709 | mTethering.interfaceStatusChanged(TEST_USB_IFNAME, true); |
| 1710 | sendUsbBroadcast(true, true, true, TETHERING_USB); |
| 1711 | mLooper.dispatchAll(); |
| 1712 | verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr))); |
Treehugger Robot | 86d212b | 2020-03-30 04:23:55 +0000 | [diff] [blame] | 1713 | verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(), |
| 1714 | any()); |
| 1715 | final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue(); |
| 1716 | assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress()); |
| 1717 | assertEquals(24, params.serverAddrPrefixLength); |
Remi NGUYEN VAN | 24d8a33 | 2020-04-24 12:19:37 +0000 | [diff] [blame] | 1718 | assertEquals(clientAddrParceled, params.singleClientAddr); |
Automerger Merge Worker | 37a2275 | 2020-03-17 16:59:57 +0000 | [diff] [blame] | 1719 | } |
| 1720 | |
Paul Hu | 77fa8d6 | 2020-04-16 02:54:37 +0000 | [diff] [blame] | 1721 | @Test |
| 1722 | public void testUpstreamNetworkChanged() { |
| 1723 | final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM) |
| 1724 | mTetheringDependencies.mUpstreamNetworkMonitorMasterSM; |
| 1725 | final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); |
| 1726 | when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState); |
| 1727 | stateMachine.chooseUpstreamType(true); |
| 1728 | |
| 1729 | verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network)); |
Chalard Jean | c0fc276 | 2020-04-17 17:12:44 +0000 | [diff] [blame] | 1730 | verify(mNotificationUpdater, times(1)).onUpstreamCapabilitiesChanged(any()); |
| 1731 | } |
| 1732 | |
| 1733 | @Test |
| 1734 | public void testUpstreamCapabilitiesChanged() { |
| 1735 | final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM) |
| 1736 | mTetheringDependencies.mUpstreamNetworkMonitorMasterSM; |
| 1737 | final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); |
| 1738 | when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState); |
| 1739 | stateMachine.chooseUpstreamType(true); |
| 1740 | |
| 1741 | stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState); |
| 1742 | // Should have two onUpstreamCapabilitiesChanged(). |
| 1743 | // One is called by reportUpstreamChanged(). One is called by EVENT_ON_CAPABILITIES. |
| 1744 | verify(mNotificationUpdater, times(2)).onUpstreamCapabilitiesChanged(any()); |
| 1745 | reset(mNotificationUpdater); |
| 1746 | |
| 1747 | // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network |
| 1748 | // capabilities changed. |
| 1749 | final UpstreamNetworkState upstreamState2 = new UpstreamNetworkState( |
| 1750 | upstreamState.linkProperties, upstreamState.networkCapabilities, new Network(101)); |
| 1751 | stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState2); |
| 1752 | verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any()); |
Paul Hu | 77fa8d6 | 2020-04-16 02:54:37 +0000 | [diff] [blame] | 1753 | } |
| 1754 | |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 1755 | @Test |
| 1756 | public void testDumpTetheringLog() throws Exception { |
| 1757 | final FileDescriptor mockFd = mock(FileDescriptor.class); |
| 1758 | final PrintWriter mockPw = mock(PrintWriter.class); |
| 1759 | runUsbTethering(null); |
Mark Chien | 47430c0 | 2020-05-08 11:00:42 +0000 | [diff] [blame] | 1760 | mLooper.startAutoDispatch(); |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 1761 | mTethering.dump(mockFd, mockPw, new String[0]); |
| 1762 | verify(mConfig).dump(any()); |
| 1763 | verify(mEntitleMgr).dump(any()); |
| 1764 | verify(mOffloadCtrl).dump(any()); |
Mark Chien | 47430c0 | 2020-05-08 11:00:42 +0000 | [diff] [blame] | 1765 | mLooper.stopAutoDispatch(); |
Mark Chien | 66b9a4a | 2020-05-07 03:49:42 +0000 | [diff] [blame] | 1766 | } |
| 1767 | |
markchien | 5788f2a | 2020-05-08 18:55:26 +0800 | [diff] [blame] | 1768 | @Test |
| 1769 | public void testExemptFromEntitlementCheck() throws Exception { |
| 1770 | setupForRequiredProvisioning(); |
| 1771 | final TetheringRequestParcel wifiNotExemptRequest = |
| 1772 | createTetheringRequestParcel(TETHERING_WIFI, null, null, false); |
| 1773 | mTethering.startTethering(wifiNotExemptRequest, null); |
| 1774 | mLooper.dispatchAll(); |
| 1775 | verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false); |
| 1776 | verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI); |
| 1777 | assertFalse(mEntitleMgr.isCellularUpstreamPermitted()); |
| 1778 | mTethering.stopTethering(TETHERING_WIFI); |
| 1779 | mLooper.dispatchAll(); |
| 1780 | verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); |
| 1781 | reset(mEntitleMgr); |
| 1782 | |
| 1783 | setupForRequiredProvisioning(); |
| 1784 | final TetheringRequestParcel wifiExemptRequest = |
| 1785 | createTetheringRequestParcel(TETHERING_WIFI, null, null, true); |
| 1786 | mTethering.startTethering(wifiExemptRequest, null); |
| 1787 | mLooper.dispatchAll(); |
| 1788 | verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false); |
| 1789 | verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI); |
| 1790 | assertTrue(mEntitleMgr.isCellularUpstreamPermitted()); |
| 1791 | mTethering.stopTethering(TETHERING_WIFI); |
| 1792 | mLooper.dispatchAll(); |
| 1793 | verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); |
| 1794 | reset(mEntitleMgr); |
| 1795 | |
| 1796 | // If one app enables tethering without provisioning check first, then another app enables |
| 1797 | // tethering of the same type but does not disable the provisioning check. |
| 1798 | setupForRequiredProvisioning(); |
| 1799 | mTethering.startTethering(wifiExemptRequest, null); |
| 1800 | mLooper.dispatchAll(); |
| 1801 | verify(mEntitleMgr, never()).startProvisioningIfNeeded(TETHERING_WIFI, false); |
| 1802 | verify(mEntitleMgr).setExemptedDownstreamType(TETHERING_WIFI); |
| 1803 | assertTrue(mEntitleMgr.isCellularUpstreamPermitted()); |
| 1804 | reset(mEntitleMgr); |
| 1805 | setupForRequiredProvisioning(); |
| 1806 | mTethering.startTethering(wifiNotExemptRequest, null); |
| 1807 | mLooper.dispatchAll(); |
| 1808 | verify(mEntitleMgr).startProvisioningIfNeeded(TETHERING_WIFI, false); |
| 1809 | verify(mEntitleMgr, never()).setExemptedDownstreamType(TETHERING_WIFI); |
| 1810 | assertFalse(mEntitleMgr.isCellularUpstreamPermitted()); |
| 1811 | mTethering.stopTethering(TETHERING_WIFI); |
| 1812 | mLooper.dispatchAll(); |
| 1813 | verify(mEntitleMgr).stopProvisioningIfNeeded(TETHERING_WIFI); |
| 1814 | reset(mEntitleMgr); |
| 1815 | } |
| 1816 | |
| 1817 | private void setupForRequiredProvisioning() { |
| 1818 | // Produce some acceptable looking provision app setting if requested. |
| 1819 | when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) |
| 1820 | .thenReturn(PROVISIONING_APP_NAME); |
| 1821 | when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui)) |
| 1822 | .thenReturn(PROVISIONING_NO_UI_APP_NAME); |
| 1823 | // Act like the CarrierConfigManager is present and ready unless told otherwise. |
| 1824 | when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) |
| 1825 | .thenReturn(mCarrierConfigManager); |
| 1826 | when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig); |
| 1827 | mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); |
| 1828 | mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); |
| 1829 | sendConfigurationChanged(); |
| 1830 | } |
Erik Kline | 1fdc2e2 | 2017-05-08 17:56:35 +0900 | [diff] [blame] | 1831 | // TODO: Test that a request for hotspot mode doesn't interfere with an |
Erik Kline | ea9cc48 | 2017-03-10 19:35:34 +0900 | [diff] [blame] | 1832 | // already operating tethering mode interface. |
Christopher Wiley | 497c147 | 2016-10-11 13:26:03 -0700 | [diff] [blame] | 1833 | } |