Merge "Update APIs based on API review feedback" into sc-dev
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index 4eafc2a..89f1505 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -36,6 +36,7 @@
"networkstack-client",
"android.hardware.tetheroffload.config-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
+ "android.hardware.tetheroffload.control-V1.1-java",
"net-utils-framework-common",
"net-utils-device-common",
"netd-client",
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadController.java b/Tethering/src/com/android/networkstack/tethering/OffloadController.java
index 88c77b0..44e3916 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadController.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadController.java
@@ -26,6 +26,7 @@
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
import android.annotation.NonNull;
@@ -96,7 +97,8 @@
private final SharedLog mLog;
private final HashMap<String, LinkProperties> mDownstreams;
private boolean mConfigInitialized;
- private boolean mControlInitialized;
+ @OffloadHardwareInterface.OffloadHalVersion
+ private int mControlHalVersion;
private LinkProperties mUpstreamLinkProperties;
// The complete set of offload-exempt prefixes passed in via Tethering from
// all upstream and downstream sources.
@@ -179,7 +181,7 @@
}
}
- mControlInitialized = mHwInterface.initOffloadControl(
+ mControlHalVersion = mHwInterface.initOffloadControl(
// OffloadHardwareInterface guarantees that these callback
// methods are called on the handler passed to it, which is the
// same as mHandler, as coordinated by the setup in Tethering.
@@ -278,7 +280,7 @@
updateStatsForCurrentUpstream();
mUpstreamLinkProperties = null;
mHwInterface.stopOffloadControl();
- mControlInitialized = false;
+ mControlHalVersion = OFFLOAD_HAL_VERSION_NONE;
mConfigInitialized = false;
if (mHandler.hasCallbacks(mScheduledPollingTask)) {
mHandler.removeCallbacks(mScheduledPollingTask);
@@ -287,7 +289,7 @@
}
private boolean started() {
- return mConfigInitialized && mControlInitialized;
+ return mConfigInitialized && mControlHalVersion != OFFLOAD_HAL_VERSION_NONE;
}
@VisibleForTesting
@@ -696,6 +698,8 @@
}
final boolean isStarted = started();
pw.println("Offload HALs " + (isStarted ? "started" : "not started"));
+ pw.println("Offload Control HAL version: "
+ + OffloadHardwareInterface.halVerToString(mControlHalVersion));
LinkProperties lp = mUpstreamLinkProperties;
String upstream = (lp != null) ? lp.getInterfaceName() : null;
pw.println("Current upstream: " + upstream);
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index da5f25b..7685847 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -20,6 +20,7 @@
import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import static android.net.util.TetheringUtils.uint16;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
@@ -38,12 +39,15 @@
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InterruptedIOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
@@ -82,6 +86,37 @@
private final SharedLog mLog;
private final Dependencies mDeps;
private IOffloadControl mOffloadControl;
+
+ // TODO: Use major-minor version control to prevent from defining new constants.
+ static final int OFFLOAD_HAL_VERSION_NONE = 0;
+ static final int OFFLOAD_HAL_VERSION_1_0 = 1;
+ static final int OFFLOAD_HAL_VERSION_1_1 = 2;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "OFFLOAD_HAL_VERSION_", value = {
+ OFFLOAD_HAL_VERSION_NONE,
+ OFFLOAD_HAL_VERSION_1_0,
+ OFFLOAD_HAL_VERSION_1_1
+ })
+ public @interface OffloadHalVersion {}
+ @OffloadHalVersion
+ private int mOffloadControlVersion = OFFLOAD_HAL_VERSION_NONE;
+
+ @NonNull
+ static String halVerToString(int version) {
+ switch(version) {
+ case OFFLOAD_HAL_VERSION_1_0:
+ return "1.0";
+ case OFFLOAD_HAL_VERSION_1_1:
+ return "1.1";
+ case OFFLOAD_HAL_VERSION_NONE:
+ return "None";
+ default:
+ throw new IllegalArgumentException("Unsupported version int " + version);
+ }
+
+ }
+
private TetheringOffloadCallback mTetheringOffloadCallback;
private ControlCallback mControlCallback;
@@ -167,13 +202,30 @@
}
}
- public IOffloadControl getOffloadControl() {
+ @NonNull
+ public Pair<IOffloadControl, Integer> getOffloadControl() {
+ IOffloadControl hal = null;
+ int version = OFFLOAD_HAL_VERSION_NONE;
try {
- return IOffloadControl.getService(true /*retry*/);
- } catch (RemoteException | NoSuchElementException e) {
- mLog.e("tethering offload control not supported: " + e);
- return null;
+ hal = android.hardware.tetheroffload.control
+ .V1_1.IOffloadControl.getService(true /*retry*/);
+ version = OFFLOAD_HAL_VERSION_1_1;
+ } catch (NoSuchElementException e) {
+ // Unsupported by device.
+ } catch (RemoteException e) {
+ mLog.e("Unable to get offload control " + OFFLOAD_HAL_VERSION_1_1);
}
+ if (hal == null) {
+ try {
+ hal = IOffloadControl.getService(true /*retry*/);
+ version = OFFLOAD_HAL_VERSION_1_0;
+ } catch (NoSuchElementException e) {
+ // Unsupported by device.
+ } catch (RemoteException e) {
+ mLog.e("Unable to get offload control " + OFFLOAD_HAL_VERSION_1_0);
+ }
+ }
+ return new Pair<IOffloadControl, Integer>(hal, version);
}
public NativeHandle createConntrackSocket(final int groups) {
@@ -304,16 +356,25 @@
}
}
- /** Initialize the tethering offload HAL. */
- public boolean initOffloadControl(ControlCallback controlCb) {
+ /**
+ * Initialize the tethering offload HAL.
+ *
+ * @return one of {@code OFFLOAD_HAL_VERSION_*} represents the HAL version, or
+ * {@link #OFFLOAD_HAL_VERSION_NONE} if failed.
+ */
+ public int initOffloadControl(ControlCallback controlCb) {
mControlCallback = controlCb;
if (mOffloadControl == null) {
- mOffloadControl = mDeps.getOffloadControl();
+ final Pair<IOffloadControl, Integer> halAndVersion = mDeps.getOffloadControl();
+ mOffloadControl = halAndVersion.first;
+ mOffloadControlVersion = halAndVersion.second;
if (mOffloadControl == null) {
mLog.e("tethering IOffloadControl.getService() returned null");
- return false;
+ return OFFLOAD_HAL_VERSION_NONE;
}
+ mLog.i("tethering offload control version "
+ + halVerToString(mOffloadControlVersion) + " is supported.");
}
final String logmsg = String.format("initOffloadControl(%s)",
@@ -331,11 +392,11 @@
});
} catch (RemoteException e) {
record(logmsg, e);
- return false;
+ return OFFLOAD_HAL_VERSION_NONE;
}
record(logmsg, results);
- return results.mSuccess;
+ return results.mSuccess ? mOffloadControlVersion : OFFLOAD_HAL_VERSION_NONE;
}
/** Stop IOffloadControl. */
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
index ce52ae2..88f2054 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
@@ -29,6 +29,8 @@
import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_IFACE;
import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_UID;
import static com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_1;
import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
import static com.android.testutils.MiscAsserts.assertContainsAll;
import static com.android.testutils.MiscAsserts.assertThrows;
@@ -141,10 +143,10 @@
FakeSettingsProvider.clearSettingsProvider();
}
- private void setupFunctioningHardwareInterface() {
+ private void setupFunctioningHardwareInterface(int controlVersion) {
when(mHardware.initOffloadConfig()).thenReturn(true);
when(mHardware.initOffloadControl(mControlCallbackCaptor.capture()))
- .thenReturn(true);
+ .thenReturn(controlVersion);
when(mHardware.setUpstreamParameters(anyString(), any(), any(), any())).thenReturn(true);
when(mHardware.getForwardedStats(any())).thenReturn(new ForwardedStats());
when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true);
@@ -170,6 +172,7 @@
ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class);
verify(mStatsManager).registerNetworkStatsProvider(anyString(),
tetherStatsProviderCaptor.capture());
+ reset(mStatsManager);
mTetherStatsProvider = tetherStatsProviderCaptor.getValue();
assertNotNull(mTetherStatsProvider);
mTetherStatsProviderCb = new TestableNetworkStatsProviderCbBinder();
@@ -178,86 +181,72 @@
}
@Test
- public void testNoSettingsValueDefaultDisabledDoesNotStart() throws Exception {
- setupFunctioningHardwareInterface();
- when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(1);
- assertThrows(SettingNotFoundException.class, () ->
- Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED));
+ public void testStartStop() throws Exception {
+ stopOffloadController(
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/));
+ stopOffloadController(
+ startOffloadController(OFFLOAD_HAL_VERSION_1_1, true /*expectStart*/));
+ }
+ @NonNull
+ private OffloadController startOffloadController(int controlVersion, boolean expectStart)
+ throws Exception {
+ setupFunctioningHardwareInterface(controlVersion);
final OffloadController offload = makeOffloadController();
offload.start();
final InOrder inOrder = inOrder(mHardware);
inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, never()).initOffloadConfig();
- inOrder.verify(mHardware, never()).initOffloadControl(
+ inOrder.verify(mHardware, times(expectStart ? 1 : 0)).initOffloadConfig();
+ inOrder.verify(mHardware, times(expectStart ? 1 : 0)).initOffloadControl(
any(OffloadHardwareInterface.ControlCallback.class));
inOrder.verifyNoMoreInteractions();
+ // Clear counters only instead of whole mock to preserve the mocking setup.
+ clearInvocations(mHardware);
+ return offload;
+ }
+
+ private void stopOffloadController(final OffloadController offload) throws Exception {
+ final InOrder inOrder = inOrder(mHardware);
+ offload.stop();
+ inOrder.verify(mHardware, times(1)).stopOffloadControl();
+ inOrder.verifyNoMoreInteractions();
+ reset(mHardware);
+ }
+
+ @Test
+ public void testNoSettingsValueDefaultDisabledDoesNotStart() throws Exception {
+ when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(1);
+ assertThrows(SettingNotFoundException.class, () ->
+ Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED));
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, false /*expectStart*/);
}
@Test
public void testNoSettingsValueDefaultEnabledDoesStart() throws Exception {
- setupFunctioningHardwareInterface();
when(mHardware.getDefaultTetherOffloadDisabled()).thenReturn(0);
assertThrows(SettingNotFoundException.class, () ->
Settings.Global.getInt(mContentResolver, TETHER_OFFLOAD_DISABLED));
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
}
@Test
public void testSettingsAllowsStart() throws Exception {
- setupFunctioningHardwareInterface();
Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 0);
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
}
@Test
public void testSettingsDisablesStart() throws Exception {
- setupFunctioningHardwareInterface();
Settings.Global.putInt(mContentResolver, TETHER_OFFLOAD_DISABLED, 1);
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, never()).initOffloadConfig();
- inOrder.verify(mHardware, never()).initOffloadControl(anyObject());
- inOrder.verifyNoMoreInteractions();
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, false /*expectStart*/);
}
@Test
public void testSetUpstreamLinkPropertiesWorking() throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
- final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).getDefaultTetherOffloadDisabled();
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
// In reality, the UpstreamNetworkMonitor would have passed down to us
// a covering set of local prefixes representing a minimum essential
@@ -271,6 +260,7 @@
minimumLocalPrefixes.add(new IpPrefix(s));
}
offload.setLocalPrefixes(minimumLocalPrefixes);
+ final InOrder inOrder = inOrder(mHardware);
inOrder.verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
assertEquals(4, localPrefixes.size());
@@ -425,11 +415,9 @@
@Test
public void testGetForwardedStats() throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
final String ethernetIface = "eth1";
final String mobileIface = "rmnet_data0";
@@ -439,7 +427,7 @@
when(mHardware.getForwardedStats(eq(mobileIface))).thenReturn(
new ForwardedStats(999, 99999));
- InOrder inOrder = inOrder(mHardware);
+ final InOrder inOrder = inOrder(mHardware);
final LinkProperties lp = new LinkProperties();
lp.setInterfaceName(ethernetIface);
@@ -517,11 +505,9 @@
@Test
public void testSetInterfaceQuota() throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
final String ethernetIface = "eth1";
final String mobileIface = "rmnet_data0";
@@ -581,11 +567,9 @@
@Test
public void testDataLimitCallback() throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue();
callback.onStoppedLimitReached();
@@ -594,17 +578,10 @@
@Test
public void testAddRemoveDownstreams() throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
-
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
final InOrder inOrder = inOrder(mHardware);
- inOrder.verify(mHardware, times(1)).initOffloadConfig();
- inOrder.verify(mHardware, times(1)).initOffloadControl(
- any(OffloadHardwareInterface.ControlCallback.class));
- inOrder.verifyNoMoreInteractions();
// Tethering makes several calls to setLocalPrefixes() before add/remove
// downstream calls are made. This is not tested here; only the behavior
@@ -668,11 +645,9 @@
@Test
public void testControlCallbackOnStoppedUnsupportedFetchesAllStats() throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
// Pretend to set a few different upstreams (only the interface name
// matters for this test; we're ignoring IP and route information).
@@ -701,11 +676,9 @@
@Test
public void testControlCallbackOnSupportAvailableFetchesAllStatsAndPushesAllParameters()
throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
-
- final OffloadController offload = makeOffloadController();
- offload.start();
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
// Pretend to set a few different upstreams (only the interface name
// matters for this test; we're ignoring IP and route information).
@@ -780,11 +753,10 @@
@Test
public void testOnSetAlert() throws Exception {
- setupFunctioningHardwareInterface();
enableOffload();
setOffloadPollInterval(DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
- final OffloadController offload = makeOffloadController();
- offload.start();
+ final OffloadController offload =
+ startOffloadController(OFFLOAD_HAL_VERSION_1_0, true /*expectStart*/);
// Initialize with fake eth upstream.
final String ethernetIface = "eth1";
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
index 38b19dd..f4194e5 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -21,6 +21,8 @@
import static android.system.OsConstants.AF_UNIX;
import static android.system.OsConstants.SOCK_STREAM;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
@@ -45,6 +47,7 @@
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.util.Pair;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -91,8 +94,8 @@
}
@Override
- public IOffloadControl getOffloadControl() {
- return mIOffloadControl;
+ public Pair<IOffloadControl, Integer> getOffloadControl() {
+ return new Pair<IOffloadControl, Integer>(mIOffloadControl, OFFLOAD_HAL_VERSION_1_0);
}
@Override
@@ -110,6 +113,7 @@
mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
}
+ // TODO: Pass version to test version specific operations.
private void startOffloadHardwareInterface() throws Exception {
mOffloadHw.initOffloadConfig();
mOffloadHw.initOffloadControl(mControlCallback);
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 7c3dd23..fb99c8e 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -61,6 +61,8 @@
import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH;
import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_1_0;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.OFFLOAD_HAL_VERSION_NONE;
import static com.android.networkstack.tethering.TestConnectivityManager.BROADCAST_FIRST;
import static com.android.networkstack.tethering.TestConnectivityManager.CALLBACKS_FIRST;
import static com.android.networkstack.tethering.Tethering.UserRestrictionActionListener;
@@ -623,7 +625,7 @@
mInterfaceConfiguration.flags = new String[0];
when(mRouterAdvertisementDaemon.start())
.thenReturn(true);
- initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
+ initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
0 /* defaultDisabled */);
when(mOffloadHardwareInterface.getForwardedStats(any())).thenReturn(mForwardedStats);
@@ -1714,7 +1716,7 @@
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
// 1. Offload fail if no OffloadConfig.
- initOffloadConfiguration(false /* offloadConfig */, true /* offloadControl */,
+ initOffloadConfiguration(false /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
0 /* defaultDisabled */);
runUsbTethering(upstreamState);
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
@@ -1722,7 +1724,7 @@
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
reset(mUsbManager);
// 2. Offload fail if no OffloadControl.
- initOffloadConfiguration(true /* offloadConfig */, false /* offloadControl */,
+ initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_NONE,
0 /* defaultDisabled */);
runUsbTethering(upstreamState);
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
@@ -1730,7 +1732,7 @@
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
reset(mUsbManager);
// 3. Offload fail if disabled by settings.
- initOffloadConfiguration(true /* offloadConfig */, true /* offloadControl */,
+ initOffloadConfiguration(true /* offloadConfig */, OFFLOAD_HAL_VERSION_1_0,
1 /* defaultDisabled */);
runUsbTethering(upstreamState);
callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_FAILED);
@@ -1746,9 +1748,10 @@
}
private void initOffloadConfiguration(final boolean offloadConfig,
- final boolean offloadControl, final int defaultDisabled) {
+ @OffloadHardwareInterface.OffloadHalVersion final int offloadControlVersion,
+ final int defaultDisabled) {
when(mOffloadHardwareInterface.initOffloadConfig()).thenReturn(offloadConfig);
- when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControl);
+ when(mOffloadHardwareInterface.initOffloadControl(any())).thenReturn(offloadControlVersion);
when(mOffloadHardwareInterface.getDefaultTetherOffloadDisabled()).thenReturn(
defaultDisabled);
}
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index a7e2bd7..3b47100 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -36,6 +36,9 @@
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
+ <!-- TODO (b/186093901): remove after fixing resource querying -->
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+
<!-- This test also uses signature permissions through adopting the shell identity.
The permissions acquired that way include (probably not exhaustive) :
android.permission.MANAGE_TEST_NETWORKS
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index c277e4d..cbeccb8 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -131,9 +131,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.ArrayUtils;
-import com.android.modules.utils.build.SdkLevel;
import com.android.networkstack.apishim.ConnectivityManagerShimImpl;
-import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.common.ConnectivityManagerShim;
import com.android.testutils.CompatUtil;
import com.android.testutils.DevSdkIgnoreRule;
@@ -312,7 +310,7 @@
mCtsNetUtils.disconnectFromCell();
}
- if (shouldTestSApis()) {
+ if (TestUtils.shouldTestSApis()) {
runWithShellPermissionIdentity(
() -> mCmShim.setRequireVpnForUids(false, mVpnRequiredUidRanges),
NETWORK_SETTINGS);
@@ -605,7 +603,7 @@
final TestNetworkCallback systemDefaultCallback = new TestNetworkCallback();
final TestNetworkCallback perUidCallback = new TestNetworkCallback();
final Handler h = new Handler(Looper.getMainLooper());
- if (shouldTestSApis()) {
+ if (TestUtils.shouldTestSApis()) {
runWithShellPermissionIdentity(() -> {
mCmShim.registerSystemDefaultNetworkCallback(systemDefaultCallback, h);
mCmShim.registerDefaultNetworkCallbackForUid(Process.myUid(), perUidCallback, h);
@@ -628,7 +626,7 @@
assertNotNull("Did not receive onAvailable on default network callback",
defaultNetwork);
- if (shouldTestSApis()) {
+ if (TestUtils.shouldTestSApis()) {
assertNotNull("Did not receive onAvailable on system default network callback",
systemDefaultCallback.waitForAvailable());
final Network perUidNetwork = perUidCallback.waitForAvailable();
@@ -642,7 +640,7 @@
} finally {
mCm.unregisterNetworkCallback(callback);
mCm.unregisterNetworkCallback(defaultTrackingCallback);
- if (shouldTestSApis()) {
+ if (TestUtils.shouldTestSApis()) {
mCm.unregisterNetworkCallback(systemDefaultCallback);
mCm.unregisterNetworkCallback(perUidCallback);
}
@@ -1670,7 +1668,7 @@
final Network network = mCtsNetUtils.ensureWifiConnected();
final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID());
- assertNotNull("Ssid getting from WiifManager is null", ssid);
+ assertNotNull("Ssid getting from WifiManager is null", ssid);
// This package should have no NETWORK_SETTINGS permission. Verify that no ssid is contained
// in the NetworkCapabilities.
verifySsidFromQueriedNetworkCapabilities(network, ssid, false /* hasSsid */);
@@ -1721,7 +1719,7 @@
public void testRequestBackgroundNetwork() {
// Cannot use @IgnoreUpTo(Build.VERSION_CODES.R) because this test also requires API 31
// shims, and @IgnoreUpTo does not check that.
- assumeTrue(shouldTestSApis());
+ assumeTrue(TestUtils.shouldTestSApis());
// Create a tun interface. Use the returned interface name as the specifier to create
// a test network request.
@@ -1866,7 +1864,7 @@
public void testBlockedStatusCallback() {
// Cannot use @IgnoreUpTo(Build.VERSION_CODES.R) because this test also requires API 31
// shims, and @IgnoreUpTo does not check that.
- assumeTrue(shouldTestSApis());
+ assumeTrue(TestUtils.shouldTestSApis());
runWithShellPermissionIdentity(() -> doTestBlockedStatusCallback(), NETWORK_SETTINGS);
}
@@ -1900,15 +1898,7 @@
public void testLegacyLockdownEnabled() {
// Cannot use @IgnoreUpTo(Build.VERSION_CODES.R) because this test also requires API 31
// shims, and @IgnoreUpTo does not check that.
- assumeTrue(shouldTestSApis());
+ assumeTrue(TestUtils.shouldTestSApis());
runWithShellPermissionIdentity(() -> doTestLegacyLockdownEnabled(), NETWORK_SETTINGS);
}
-
- /**
- * Whether to test S+ APIs. This requires a) that the test be running on an S+ device, and
- * b) that the code be compiled against shims new enough to access these APIs.
- */
- private boolean shouldTestSApis() {
- return SdkLevel.isAtLeastS() && ConstantsShim.VERSION > Build.VERSION_CODES.R;
- }
}
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index c28bcd9..b6fa7f8 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -542,16 +542,23 @@
// Connect the first Network
createConnectedNetworkAgent(name = name1).let { (agent1, _) ->
callback.expectAvailableThenValidatedCallbacks(agent1.network)
- // Upgrade agent1 to a better score so that there is no ambiguity when
- // agent2 connects that agent1 is still better
- agent1.sendNetworkScore(BETTER_NETWORK_SCORE - 1)
+ // If using the int ranking, agent1 must be upgraded to a better score so that there is
+ // no ambiguity when agent2 connects that agent1 is still better. If using policy
+ // ranking, this is not necessary.
+ agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(BETTER_NETWORK_SCORE)
+ .build())
// Connect the second agent
createConnectedNetworkAgent(name = name2).let { (agent2, _) ->
agent2.markConnected()
- // The callback should not see anything yet
+ // The callback should not see anything yet. With int ranking, agent1 was upgraded
+ // to a stronger score beforehand. With policy ranking, agent1 is preferred by
+ // virtue of already satisfying the request.
callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
- // Now update the score and expect the callback now prefers agent2
- agent2.sendNetworkScore(BETTER_NETWORK_SCORE)
+ // Now downgrade the score and expect the callback now prefers agent2
+ agent1.sendNetworkScore(NetworkScore.Builder()
+ .setLegacyInt(WORSE_NETWORK_SCORE)
+ .setExiting(true)
+ .build())
callback.expectCallback<Available>(agent2.network)
}
}
diff --git a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
index 9906c30..1a97566 100644
--- a/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkRequestTest.java
@@ -28,10 +28,13 @@
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static junit.framework.Assert.fail;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import android.annotation.NonNull;
import android.net.MacAddress;
@@ -396,4 +399,42 @@
.addCapability(NET_CAPABILITY_DUN).build();
assertTrue(dunRequest.hasCapability(ConstantsShim.NET_CAPABILITY_NOT_VCN_MANAGED));
}
+
+ private void verifyEqualRequestBuilt(NetworkRequest orig) {
+ try {
+ final NetworkRequestShim shim = NetworkRequestShimImpl.newInstance();
+ final NetworkRequest copy = shim.newBuilder(orig).build();
+ assertEquals(orig, copy);
+ } catch (UnsupportedApiLevelException e) {
+ fail("NetworkRequestShim.newBuilder should be supported in this SDK version");
+ }
+ }
+
+ @Test
+ public void testBuildRequestFromExistingRequestWithBuilder() {
+ assumeTrue(TestUtils.shouldTestSApis());
+ final NetworkRequest.Builder builder = new NetworkRequest.Builder();
+
+ final NetworkRequest baseRequest = builder.build();
+ verifyEqualRequestBuilt(baseRequest);
+
+ final NetworkRequest requestCellMms = builder
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_MMS)
+ .setSignalStrength(-99).build();
+ verifyEqualRequestBuilt(requestCellMms);
+
+ final WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_LITERAL))
+ .setBssidPattern(ARBITRARY_ADDRESS, ARBITRARY_ADDRESS)
+ .build();
+ final NetworkRequest requestWifi = builder
+ .addTransportType(TRANSPORT_WIFI)
+ .removeTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .removeCapability(NET_CAPABILITY_MMS)
+ .setNetworkSpecifier(specifier)
+ .setSignalStrength(-33).build();
+ verifyEqualRequestBuilt(requestWifi);
+ }
}
diff --git a/tests/cts/net/src/android/net/cts/TestUtils.java b/tests/cts/net/src/android/net/cts/TestUtils.java
new file mode 100644
index 0000000..a2974b9
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/TestUtils.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.cts;
+
+import android.os.Build;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.networkstack.apishim.ConstantsShim;
+
+/**
+ * Utils class to provide common shared test helper methods or constants that behave different
+ * against compiled sdk.
+ */
+public class TestUtils {
+ /**
+ * Whether to test S+ APIs. This requires a) that the test be running on an S+ device, and
+ * b) that the code be compiled against shims new enough to access these APIs.
+ */
+ public static boolean shouldTestSApis() {
+ return SdkLevel.isAtLeastS() && ConstantsShim.VERSION > Build.VERSION_CODES.R;
+ }
+}