Merge "Add method to read trunk stable flag" into main
diff --git a/TEST_MAPPING b/TEST_MAPPING
index d33453c..fafd3bb 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,7 +1,12 @@
{
"presubmit": [
{
- "name": "ConnectivityCoverageTests"
+ "name": "ConnectivityCoverageTests",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.NetworkStackModuleTest"
+ }
+ ]
},
{
// In addition to ConnectivityCoverageTests, runs non-connectivity-module tests
diff --git a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
index a280046..4d1e7ef 100644
--- a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
+++ b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
@@ -167,7 +167,6 @@
@Override
public boolean addIpv6UpstreamRule(@NonNull final Ipv6UpstreamRule rule) {
- if (!isInitialized()) return false;
// RFC7421_PREFIX_LENGTH = 64 which is the most commonly used IPv6 subnet prefix length.
if (rule.sourcePrefix.getPrefixLength() != RFC7421_PREFIX_LENGTH) return false;
@@ -185,7 +184,6 @@
@Override
public boolean removeIpv6UpstreamRule(@NonNull final Ipv6UpstreamRule rule) {
- if (!isInitialized()) return false;
// RFC7421_PREFIX_LENGTH = 64 which is the most commonly used IPv6 subnet prefix length.
if (rule.sourcePrefix.getPrefixLength() != RFC7421_PREFIX_LENGTH) return false;
@@ -200,8 +198,6 @@
@Override
public boolean addIpv6DownstreamRule(@NonNull final Ipv6DownstreamRule rule) {
- if (!isInitialized()) return false;
-
final TetherDownstream6Key key = rule.makeTetherDownstream6Key();
final Tether6Value value = rule.makeTether6Value();
@@ -217,8 +213,6 @@
@Override
public boolean removeIpv6DownstreamRule(@NonNull final Ipv6DownstreamRule rule) {
- if (!isInitialized()) return false;
-
try {
mBpfDownstream6Map.deleteEntry(rule.makeTetherDownstream6Key());
} catch (ErrnoException e) {
@@ -234,8 +228,6 @@
@Override
@Nullable
public SparseArray<TetherStatsValue> tetherOffloadGetStats() {
- if (!isInitialized()) return null;
-
final SparseArray<TetherStatsValue> tetherStatsList = new SparseArray<TetherStatsValue>();
try {
// The reported tether stats are total data usage for all currently-active upstream
@@ -250,8 +242,6 @@
@Override
public boolean tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes) {
- if (!isInitialized()) return false;
-
// The common case is an update, where the stats already exist,
// hence we read first, even though writing with BPF_NOEXIST
// first would make the code simpler.
@@ -307,8 +297,6 @@
@Override
@Nullable
public TetherStatsValue tetherOffloadGetAndClearStats(int ifIndex) {
- if (!isInitialized()) return null;
-
// getAndClearTetherOffloadStats is called after all offload rules have already been
// deleted for the given upstream interface. Before starting to do cleanup stuff in this
// function, use synchronizeKernelRCU to make sure that all the current running eBPF
@@ -354,8 +342,6 @@
@Override
public boolean tetherOffloadRuleAdd(boolean downstream, @NonNull Tether4Key key,
@NonNull Tether4Value value) {
- if (!isInitialized()) return false;
-
try {
if (downstream) {
mBpfDownstream4Map.insertEntry(key, value);
@@ -379,8 +365,6 @@
@Override
public boolean tetherOffloadRuleRemove(boolean downstream, @NonNull Tether4Key key) {
- if (!isInitialized()) return false;
-
try {
if (downstream) {
if (!mBpfDownstream4Map.deleteEntry(key)) return false; // Rule did not exist
@@ -413,8 +397,6 @@
@Override
public void tetherOffloadRuleForEach(boolean downstream,
@NonNull ThrowingBiConsumer<Tether4Key, Tether4Value> action) {
- if (!isInitialized()) return;
-
try {
if (downstream) {
mBpfDownstream4Map.forEach(action);
@@ -428,8 +410,6 @@
@Override
public boolean attachProgram(String iface, boolean downstream, boolean ipv4) {
- if (!isInitialized()) return false;
-
try {
BpfUtils.attachProgram(iface, downstream, ipv4);
} catch (IOException e) {
@@ -441,8 +421,6 @@
@Override
public boolean detachProgram(String iface, boolean ipv4) {
- if (!isInitialized()) return false;
-
try {
BpfUtils.detachProgram(iface, ipv4);
} catch (IOException e) {
@@ -460,8 +438,6 @@
@Override
public boolean addDevMap(int ifIndex) {
- if (!isInitialized()) return false;
-
try {
mBpfDevMap.updateEntry(new TetherDevKey(ifIndex), new TetherDevValue(ifIndex));
} catch (ErrnoException e) {
@@ -473,8 +449,6 @@
@Override
public boolean removeDevMap(int ifIndex) {
- if (!isInitialized()) return false;
-
try {
mBpfDevMap.deleteEntry(new TetherDevKey(ifIndex));
} catch (ErrnoException e) {
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index a851410..e030902 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -127,6 +127,7 @@
// TODO: have this configurable
private static final int DHCP_LEASE_TIME_SECS = 3600;
+ private static final int NO_UPSTREAM = 0;
private static final MacAddress NULL_MAC_ADDRESS = MacAddress.fromString("00:00:00:00:00:00");
private static final String TAG = "IpServer";
@@ -259,6 +260,12 @@
private int mLastError;
private int mServingMode;
private InterfaceSet mUpstreamIfaceSet; // may change over time
+ // mInterfaceParams can't be final now because IpServer will be created when receives
+ // WIFI_AP_STATE_CHANGED broadcasts or when it detects that the wifi interface has come up.
+ // In the latter case, the interface is not fully initialized and the MAC address might not
+ // be correct (it will be set with a randomized MAC address later).
+ // TODO: Consider create the IpServer only when tethering want to enable it, then we can
+ // make mInterfaceParams final.
private InterfaceParams mInterfaceParams;
// TODO: De-duplicate this with mLinkProperties above. Currently, these link
// properties are those selected by the IPv6TetheringCoordinator and relayed
@@ -740,7 +747,7 @@
RaParams params = null;
String upstreamIface = null;
InterfaceParams upstreamIfaceParams = null;
- int upstreamIfIndex = 0;
+ int upstreamIfIndex = NO_UPSTREAM;
if (v6only != null) {
upstreamIface = v6only.getInterfaceName();
@@ -772,7 +779,7 @@
// CMD_TETHER_CONNECTION_CHANGED. Adding the mapping update here to the avoid potential
// timing issue. It prevents that the IPv6 capability is updated later than
// CMD_TETHER_CONNECTION_CHANGED.
- mBpfCoordinator.addUpstreamNameToLookupTable(upstreamIfIndex, upstreamIface);
+ mBpfCoordinator.maybeAddUpstreamToLookupTable(upstreamIfIndex, upstreamIface);
// If v6only is null, we pass in null to setRaParams(), which handles
// deprecation of any existing RA data.
@@ -780,8 +787,7 @@
// Not support BPF on virtual upstream interface
final boolean upstreamSupportsBpf = upstreamIface != null && !isVcnInterface(upstreamIface);
- updateIpv6ForwardingRules(
- mLastIPv6UpstreamIfindex, upstreamIfIndex, upstreamSupportsBpf, null);
+ updateIpv6ForwardingRules(mLastIPv6UpstreamIfindex, upstreamIfIndex, upstreamSupportsBpf);
mLastIPv6LinkProperties = v6only;
mLastIPv6UpstreamIfindex = upstreamIfIndex;
mUpstreamSupportsBpf = upstreamSupportsBpf;
@@ -887,25 +893,23 @@
}
}
- // Handles all updates to IPv6 forwarding rules. These can currently change only if the upstream
- // changes or if a neighbor event is received.
+ private int getInterfaceIndexForRule(int ifindex, boolean supportsBpf) {
+ return supportsBpf ? ifindex : NO_UPSTREAM;
+ }
+
+ // Handles updates to IPv6 forwarding rules if the upstream changes.
private void updateIpv6ForwardingRules(int prevUpstreamIfindex, int upstreamIfindex,
- boolean upstreamSupportsBpf, NeighborEvent e) {
- // If no longer have an upstream or upstream not supports BPF, clear forwarding rules and do
- // nothing else.
- // TODO: Rather than always clear rules, ensure whether ipv6 ever enable first.
- if (upstreamIfindex == 0 || !upstreamSupportsBpf) {
- mBpfCoordinator.tetherOffloadRuleClear(this);
- return;
- }
-
+ boolean upstreamSupportsBpf) {
// If the upstream interface has changed, remove all rules and re-add them with the new
- // upstream interface.
+ // upstream interface. If upstream is a virtual network, treated as no upstream.
if (prevUpstreamIfindex != upstreamIfindex) {
- mBpfCoordinator.tetherOffloadRuleUpdate(this, upstreamIfindex);
+ mBpfCoordinator.updateAllIpv6Rules(this, this.mInterfaceParams,
+ getInterfaceIndexForRule(upstreamIfindex, upstreamSupportsBpf));
}
+ }
- // If we're here to process a NeighborEvent, do so now.
+ // Handles updates to IPv6 downstream rules if a neighbor event is received.
+ private void addOrRemoveIpv6Downstream(NeighborEvent e) {
// mInterfaceParams must be non-null or the event would not have arrived.
if (e == null) return;
if (!(e.ip instanceof Inet6Address) || e.ip.isMulticastAddress()
@@ -917,8 +921,9 @@
// Do this here instead of in the Ipv6DownstreamRule constructor to ensure that we
// never add rules with a null MAC, only delete them.
MacAddress dstMac = e.isValid() ? e.macAddr : NULL_MAC_ADDRESS;
- Ipv6DownstreamRule rule = new Ipv6DownstreamRule(upstreamIfindex, mInterfaceParams.index,
- (Inet6Address) e.ip, mInterfaceParams.macAddr, dstMac);
+ Ipv6DownstreamRule rule = new Ipv6DownstreamRule(
+ getInterfaceIndexForRule(mLastIPv6UpstreamIfindex, mUpstreamSupportsBpf),
+ mInterfaceParams.index, (Inet6Address) e.ip, mInterfaceParams.macAddr, dstMac);
if (e.isValid()) {
mBpfCoordinator.addIpv6DownstreamRule(this, rule);
} else {
@@ -951,8 +956,7 @@
if (mInterfaceParams != null
&& mInterfaceParams.index == e.ifindex
&& mInterfaceParams.hasMacAddress) {
- updateIpv6ForwardingRules(mLastIPv6UpstreamIfindex, mLastIPv6UpstreamIfindex,
- mUpstreamSupportsBpf, e);
+ addOrRemoveIpv6Downstream(e);
updateClientInfoIpv4(e);
}
}
@@ -1285,6 +1289,7 @@
@Override
public void exit() {
cleanupUpstream();
+ mBpfCoordinator.clearAllIpv6Rules(IpServer.this);
super.exit();
}
@@ -1303,7 +1308,8 @@
for (String ifname : mUpstreamIfaceSet.ifnames) cleanupUpstreamInterface(ifname);
mUpstreamIfaceSet = null;
- mBpfCoordinator.tetherOffloadRuleClear(IpServer.this);
+ mBpfCoordinator.updateAllIpv6Rules(
+ IpServer.this, IpServer.this.mInterfaceParams, NO_UPSTREAM);
}
private void cleanupUpstreamInterface(String upstreamIface) {
@@ -1370,7 +1376,7 @@
final InterfaceParams upstreamIfaceParams =
mDeps.getInterfaceParams(ifname);
if (upstreamIfaceParams != null) {
- mBpfCoordinator.addUpstreamNameToLookupTable(
+ mBpfCoordinator.maybeAddUpstreamToLookupTable(
upstreamIfaceParams.index, ifname);
}
}
@@ -1430,6 +1436,8 @@
class UnavailableState extends State {
@Override
public void enter() {
+ // TODO: move mIpNeighborMonitor.stop() to TetheredState#exit, and trigger a neighbours
+ // dump after starting mIpNeighborMonitor.
mIpNeighborMonitor.stop();
mLastError = TETHER_ERROR_NO_ERROR;
sendInterfaceState(STATE_UNAVAILABLE);
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 1b23a6c..46c815f 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -50,6 +50,7 @@
import android.system.ErrnoException;
import android.system.OsConstants;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
@@ -153,6 +154,7 @@
static final int NF_CONNTRACK_UDP_TIMEOUT_STREAM = 180;
@VisibleForTesting
static final int INVALID_MTU = 0;
+ static final int NO_UPSTREAM = 0;
// List of TCP port numbers which aren't offloaded because the packets require the netfilter
// conntrack helper. See also TetherController::setForwardRules in netd.
@@ -221,6 +223,23 @@
// TODO: Remove the unused interface name.
private final SparseArray<String> mInterfaceNames = new SparseArray<>();
+ // How IPv6 upstream rules and downstream rules are managed in BpfCoordinator:
+ // 1. Each upstream rule represents a downstream interface to an upstream interface forwarding.
+ // No upstream rule will be exist if there is no upstream interface.
+ // Note that there is at most one upstream interface for a given downstream interface.
+ // 2. Each downstream rule represents an IPv6 neighbor, regardless of the existence of the
+ // upstream interface. If the upstream is not present, the downstream rules have an upstream
+ // interface index of NO_UPSTREAM, only exist in BpfCoordinator and won't be written to the
+ // BPF map. When the upstream comes back, those downstream rules will be updated by calling
+ // Ipv6DownstreamRule#onNewUpstream and written to the BPF map again. We don't remove the
+ // downstream rules when upstream is lost is because the upstream may come back with the
+ // same prefix and we won't receive any neighbor update event in this case.
+ // TODO: Remove downstream rules when upstream is lost and dump neighbors table when upstream
+ // interface comes back in order to reconstruct the downstream rules.
+ // 3. It is the same thing for BpfCoordinator if there is no upstream interface or the upstream
+ // interface is a virtual interface (which currently not supports BPF). In this case,
+ // IpServer will update its upstream ifindex to NO_UPSTREAM to the BpfCoordinator.
+
// Map of downstream rule maps. Each of these maps represents the IPv6 forwarding rules for a
// given downstream. Each map:
// - Is owned by the IpServer that is responsible for that downstream.
@@ -240,6 +259,16 @@
private final HashMap<IpServer, LinkedHashMap<Inet6Address, Ipv6DownstreamRule>>
mIpv6DownstreamRules = new LinkedHashMap<>();
+ // Map of IPv6 upstream rules maps. Each of these maps represents the IPv6 upstream rules for a
+ // given downstream. Each map:
+ // - Is owned by the IpServer that is responsible for that downstream.
+ // - Must only be modified by that IpServer.
+ // - Is created when the IpServer adds its first upstream rule, and deleted when the IpServer
+ // deletes its last upstream rule (or clears its upstream rules)
+ // - Each upstream rule in the ArraySet is corresponding to an upstream interface.
+ private final ArrayMap<IpServer, ArraySet<Ipv6UpstreamRule>>
+ mIpv6UpstreamRules = new ArrayMap<>();
+
// Map of downstream client maps. Each of these maps represents the IPv4 clients for a given
// downstream. Needed to build IPv4 forwarding rules when conntrack events are received.
// Each map:
@@ -603,130 +632,173 @@
}
/**
- * Add IPv6 downstream rule. After adding the first rule on a given upstream, must add the data
- * limit on the given upstream.
- * Note that this can be only called on handler thread.
+ * Add IPv6 upstream rule. After adding the first rule on a given upstream, must add the
+ * data limit on the given upstream.
*/
- public void addIpv6DownstreamRule(
- @NonNull final IpServer ipServer, @NonNull final Ipv6DownstreamRule rule) {
+ private void addIpv6UpstreamRule(
+ @NonNull final IpServer ipServer, @NonNull final Ipv6UpstreamRule rule) {
if (!isUsingBpf()) return;
- // TODO: Perhaps avoid to add a duplicate rule.
- if (!mBpfCoordinatorShim.addIpv6DownstreamRule(rule)) return;
-
- if (!mIpv6DownstreamRules.containsKey(ipServer)) {
- mIpv6DownstreamRules.put(ipServer, new LinkedHashMap<Inet6Address,
- Ipv6DownstreamRule>());
- }
- LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules = mIpv6DownstreamRules.get(ipServer);
-
// Add upstream and downstream interface index to dev map.
maybeAddDevMap(rule.upstreamIfindex, rule.downstreamIfindex);
// When the first rule is added to an upstream, setup upstream forwarding and data limit.
maybeSetLimit(rule.upstreamIfindex);
- if (!isAnyRuleFromDownstreamToUpstream(rule.downstreamIfindex, rule.upstreamIfindex)) {
- // TODO: support upstream forwarding on non-point-to-point interfaces.
- // TODO: get the MTU from LinkProperties and update the rules when it changes.
- Ipv6UpstreamRule upstreamRule = new Ipv6UpstreamRule(rule.upstreamIfindex,
- rule.downstreamIfindex, IPV6_ZERO_PREFIX64, rule.srcMac, NULL_MAC_ADDRESS,
- NULL_MAC_ADDRESS);
- if (!mBpfCoordinatorShim.addIpv6UpstreamRule(upstreamRule)) {
- mLog.e("Failed to add upstream IPv6 forwarding rule: " + upstreamRule);
- }
+ // TODO: support upstream forwarding on non-point-to-point interfaces.
+ // TODO: get the MTU from LinkProperties and update the rules when it changes.
+ if (!mBpfCoordinatorShim.addIpv6UpstreamRule(rule)) {
+ return;
}
- // Must update the adding rule after calling #isAnyRuleOnUpstream because it needs to
- // check if it is about adding a first rule for a given upstream.
+ ArraySet<Ipv6UpstreamRule> rules = mIpv6UpstreamRules.computeIfAbsent(
+ ipServer, k -> new ArraySet<Ipv6UpstreamRule>());
+ rules.add(rule);
+ }
+
+ /**
+ * Clear all IPv6 upstream rules for a given downstream. After removing the last rule on a given
+ * upstream, must clear data limit, update the last tether stats and remove the tether stats in
+ * the BPF maps.
+ */
+ private void clearIpv6UpstreamRules(@NonNull final IpServer ipServer) {
+ if (!isUsingBpf()) return;
+
+ final ArraySet<Ipv6UpstreamRule> upstreamRules = mIpv6UpstreamRules.remove(ipServer);
+ if (upstreamRules == null) return;
+
+ int upstreamIfindex = 0;
+ for (Ipv6UpstreamRule rule: upstreamRules) {
+ if (upstreamIfindex != 0 && rule.upstreamIfindex != upstreamIfindex) {
+ Log.wtf(TAG, "BUG: upstream rules point to more than one interface");
+ }
+ upstreamIfindex = rule.upstreamIfindex;
+ mBpfCoordinatorShim.removeIpv6UpstreamRule(rule);
+ }
+ // Clear the limit if there are no more rules on the given upstream.
+ // Using upstreamIfindex outside the loop is fine because all the rules for a given IpServer
+ // will always have the same upstream index (since they are always added all together by
+ // updateAllIpv6Rules).
+ // The upstreamIfindex can't be 0 because we won't add an Ipv6UpstreamRule with
+ // upstreamIfindex == 0 and if there is no Ipv6UpstreamRule for an IpServer, it will be
+ // removed from mIpv6UpstreamRules.
+ if (upstreamIfindex == 0) {
+ Log.wtf(TAG, "BUG: upstream rules have empty Set or rule.upstreamIfindex == 0");
+ return;
+ }
+ maybeClearLimit(upstreamIfindex);
+ }
+
+ /**
+ * Add IPv6 downstream rule.
+ * Note that this can be only called on handler thread.
+ */
+ public void addIpv6DownstreamRule(
+ @NonNull final IpServer ipServer, @NonNull final Ipv6DownstreamRule rule) {
+ if (!isUsingBpf()) return;
+
+ // TODO: Perhaps avoid to add a duplicate rule.
+ if (rule.upstreamIfindex != NO_UPSTREAM
+ && !mBpfCoordinatorShim.addIpv6DownstreamRule(rule)) return;
+
+ LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules =
+ mIpv6DownstreamRules.computeIfAbsent(ipServer,
+ k -> new LinkedHashMap<Inet6Address, Ipv6DownstreamRule>());
rules.put(rule.address, rule);
}
/**
- * Remove IPv6 downstream rule. After removing the last rule on a given upstream, must clear
- * data limit, update the last tether stats and remove the tether stats in the BPF maps.
+ * Remove IPv6 downstream rule.
* Note that this can be only called on handler thread.
*/
public void removeIpv6DownstreamRule(
@NonNull final IpServer ipServer, @NonNull final Ipv6DownstreamRule rule) {
if (!isUsingBpf()) return;
- if (!mBpfCoordinatorShim.removeIpv6DownstreamRule(rule)) return;
+ if (rule.upstreamIfindex != NO_UPSTREAM
+ && !mBpfCoordinatorShim.removeIpv6DownstreamRule(rule)) return;
LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules = mIpv6DownstreamRules.get(ipServer);
if (rules == null) return;
- // Must remove rules before calling #isAnyRuleOnUpstream because it needs to check if
- // the last rule is removed for a given upstream. If no rule is removed, return early.
- // Avoid unnecessary work on a non-existent rule which may have never been added or
- // removed already.
+ // If no rule is removed, return early. Avoid unnecessary work on a non-existent rule which
+ // may have never been added or removed already.
if (rules.remove(rule.address) == null) return;
// Remove the downstream entry if it has no more rule.
if (rules.isEmpty()) {
mIpv6DownstreamRules.remove(ipServer);
}
+ }
- // If no more rules between this upstream and downstream, stop upstream forwarding.
- if (!isAnyRuleFromDownstreamToUpstream(rule.downstreamIfindex, rule.upstreamIfindex)) {
- Ipv6UpstreamRule upstreamRule = new Ipv6UpstreamRule(rule.upstreamIfindex,
- rule.downstreamIfindex, IPV6_ZERO_PREFIX64, rule.srcMac, NULL_MAC_ADDRESS,
- NULL_MAC_ADDRESS);
- if (!mBpfCoordinatorShim.removeIpv6UpstreamRule(upstreamRule)) {
- mLog.e("Failed to remove upstream IPv6 forwarding rule: " + upstreamRule);
- }
+ /**
+ * Clear all downstream rules for a given IpServer and return a copy of all removed rules.
+ */
+ @Nullable
+ private Collection<Ipv6DownstreamRule> clearIpv6DownstreamRules(
+ @NonNull final IpServer ipServer) {
+ final LinkedHashMap<Inet6Address, Ipv6DownstreamRule> downstreamRules =
+ mIpv6DownstreamRules.remove(ipServer);
+ if (downstreamRules == null) return null;
+
+ final Collection<Ipv6DownstreamRule> removedRules = downstreamRules.values();
+ for (final Ipv6DownstreamRule rule : removedRules) {
+ if (rule.upstreamIfindex == NO_UPSTREAM) continue;
+ mBpfCoordinatorShim.removeIpv6DownstreamRule(rule);
}
-
- // Do cleanup functionality if there is no more rule on the given upstream.
- maybeClearLimit(rule.upstreamIfindex);
+ return removedRules;
}
/**
* Clear all forwarding rules for a given downstream.
* Note that this can be only called on handler thread.
- * TODO: rename to tetherOffloadRuleClear6 because of IPv6 only.
*/
- public void tetherOffloadRuleClear(@NonNull final IpServer ipServer) {
+ public void clearAllIpv6Rules(@NonNull final IpServer ipServer) {
if (!isUsingBpf()) return;
- final LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules =
- mIpv6DownstreamRules.get(ipServer);
- if (rules == null) return;
-
- // Need to build a rule list because the rule map may be changed in the iteration.
- for (final Ipv6DownstreamRule rule : new ArrayList<Ipv6DownstreamRule>(rules.values())) {
- removeIpv6DownstreamRule(ipServer, rule);
- }
+ // Clear downstream rules first, because clearing upstream rules fetches the stats, and
+ // fetching the stats requires that no rules be forwarding traffic to or from the upstream.
+ clearIpv6DownstreamRules(ipServer);
+ clearIpv6UpstreamRules(ipServer);
}
/**
- * Update existing forwarding rules to new upstream for a given downstream.
+ * Delete all upstream and downstream rules for the passed-in IpServer, and if the new upstream
+ * is nonzero, reapply them to the new upstream.
* Note that this can be only called on handler thread.
*/
- public void tetherOffloadRuleUpdate(@NonNull final IpServer ipServer, int newUpstreamIfindex) {
+ public void updateAllIpv6Rules(@NonNull final IpServer ipServer,
+ final InterfaceParams interfaceParams, int newUpstreamIfindex) {
if (!isUsingBpf()) return;
- final LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules =
- mIpv6DownstreamRules.get(ipServer);
- if (rules == null) return;
+ // Remove IPv6 downstream rules. Remove the old ones before adding the new rules, otherwise
+ // we need to keep a copy of the old rules.
+ // We still need to keep the downstream rules even when the upstream goes away because it
+ // may come back with the same prefixes (unlikely, but possible). Neighbor entries won't be
+ // deleted and we're not expected to receive new Neighbor events in this case.
+ // TODO: Add new rule first to reduce the latency which has no rule. But this is okay
+ // because if this is a new upstream, it will probably have different prefixes than
+ // the one these downstream rules are in. If so, they will never see any downstream
+ // traffic before new neighbor entries are created.
+ final Collection<Ipv6DownstreamRule> deletedDownstreamRules =
+ clearIpv6DownstreamRules(ipServer);
- // Need to build a rule list because the rule map may be changed in the iteration.
- // First remove all the old rules, then add all the new rules. This is because the upstream
- // forwarding code in addIpv6DownstreamRule cannot support rules on two upstreams at the
- // same time. Deleting the rules first ensures that upstream forwarding is disabled on the
- // old upstream when the last rule is removed from it, and re-enabled on the new upstream
- // when the first rule is added to it.
- // TODO: Once the IPv6 client processing code has moved from IpServer to BpfCoordinator, do
- // something smarter.
- final ArrayList<Ipv6DownstreamRule> rulesCopy = new ArrayList<>(rules.values());
- for (final Ipv6DownstreamRule rule : rulesCopy) {
- // Remove the old rule before adding the new one because the map uses the same key for
- // both rules. Reversing the processing order causes that the new rule is removed as
- // unexpected.
- // TODO: Add new rule first to reduce the latency which has no rule.
- removeIpv6DownstreamRule(ipServer, rule);
+ // Remove IPv6 upstream rules. Downstream rules must be removed first because
+ // BpfCoordinatorShimImpl#tetherOffloadGetAndClearStats will be called after the removal of
+ // the last upstream rule and it requires that no rules be forwarding traffic to or from
+ // that upstream.
+ clearIpv6UpstreamRules(ipServer);
+
+ // Add new upstream rules.
+ if (newUpstreamIfindex != 0 && interfaceParams != null && interfaceParams.macAddr != null) {
+ addIpv6UpstreamRule(ipServer, new Ipv6UpstreamRule(
+ newUpstreamIfindex, interfaceParams.index, IPV6_ZERO_PREFIX64,
+ interfaceParams.macAddr, NULL_MAC_ADDRESS, NULL_MAC_ADDRESS));
}
- for (final Ipv6DownstreamRule rule : rulesCopy) {
+
+ // Add updated downstream rules.
+ if (deletedDownstreamRules == null) return;
+ for (final Ipv6DownstreamRule rule : deletedDownstreamRules) {
addIpv6DownstreamRule(ipServer, rule.onNewUpstream(newUpstreamIfindex));
}
}
@@ -737,7 +809,7 @@
* expects the interface name in NetworkStats object.
* Note that this can be only called on handler thread.
*/
- public void addUpstreamNameToLookupTable(int upstreamIfindex, @NonNull String upstreamIface) {
+ public void maybeAddUpstreamToLookupTable(int upstreamIfindex, @Nullable String upstreamIface) {
if (!isUsingBpf()) return;
if (upstreamIfindex == 0 || TextUtils.isEmpty(upstreamIface)) return;
@@ -1007,7 +1079,7 @@
* TODO: consider error handling if the attach program failed.
*/
public void maybeAttachProgram(@NonNull String intIface, @NonNull String extIface) {
- if (isVcnInterface(extIface)) return;
+ if (!isUsingBpf() || isVcnInterface(extIface)) return;
if (forwardingPairExists(intIface, extIface)) return;
@@ -1031,6 +1103,8 @@
* Detach BPF program
*/
public void maybeDetachProgram(@NonNull String intIface, @NonNull String extIface) {
+ if (!isUsingBpf()) return;
+
forwardingPairRemove(intIface, extIface);
// Detaching program may fail because the interface has been removed already.
@@ -1967,9 +2041,8 @@
}
private int getInterfaceIndexFromRules(@NonNull String ifName) {
- for (LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules :
- mIpv6DownstreamRules.values()) {
- for (Ipv6DownstreamRule rule : rules.values()) {
+ for (ArraySet<Ipv6UpstreamRule> rules : mIpv6UpstreamRules.values()) {
+ for (Ipv6UpstreamRule rule : rules) {
final int upstreamIfindex = rule.upstreamIfindex;
if (TextUtils.equals(ifName, mInterfaceNames.get(upstreamIfindex))) {
return upstreamIfindex;
@@ -1987,6 +2060,7 @@
}
private boolean sendDataLimitToBpfMap(int ifIndex, long quotaBytes) {
+ if (!isUsingBpf()) return false;
if (ifIndex == 0) {
Log.wtf(TAG, "Invalid interface index.");
return false;
@@ -2060,28 +2134,14 @@
// TODO: Rename to isAnyIpv6RuleOnUpstream and define an isAnyRuleOnUpstream method that called
// both isAnyIpv6RuleOnUpstream and mBpfCoordinatorShim.isAnyIpv4RuleOnUpstream.
private boolean isAnyRuleOnUpstream(int upstreamIfindex) {
- for (LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules :
- mIpv6DownstreamRules.values()) {
- for (Ipv6DownstreamRule rule : rules.values()) {
+ for (ArraySet<Ipv6UpstreamRule> rules : mIpv6UpstreamRules.values()) {
+ for (Ipv6UpstreamRule rule : rules) {
if (upstreamIfindex == rule.upstreamIfindex) return true;
}
}
return false;
}
- private boolean isAnyRuleFromDownstreamToUpstream(int downstreamIfindex, int upstreamIfindex) {
- for (LinkedHashMap<Inet6Address, Ipv6DownstreamRule> rules :
- mIpv6DownstreamRules.values()) {
- for (Ipv6DownstreamRule rule : rules.values()) {
- if (downstreamIfindex == rule.downstreamIfindex
- && upstreamIfindex == rule.upstreamIfindex) {
- return true;
- }
- }
- }
- return false;
- }
-
// TODO: remove the index from map while the interface has been removed because the map size
// is 64 entries. See packages\modules\Connectivity\Tethering\bpf_progs\offload.c.
private void maybeAddDevMap(int upstreamIfindex, int downstreamIfindex) {
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index c0718d1..d497a4d 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -158,6 +158,7 @@
private static final String UPSTREAM_IFACE = "upstream0";
private static final String UPSTREAM_IFACE2 = "upstream1";
private static final String IPSEC_IFACE = "ipsec0";
+ private static final int NO_UPSTREAM = 0;
private static final int UPSTREAM_IFINDEX = 101;
private static final int UPSTREAM_IFINDEX2 = 102;
private static final int IPSEC_IFINDEX = 103;
@@ -274,8 +275,18 @@
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(upstreamIface);
dispatchTetherConnectionChanged(upstreamIface, lp, 0);
+ if (usingBpfOffload) {
+ InterfaceParams interfaceParams = mDependencies.getInterfaceParams(upstreamIface);
+ assertNotNull("missing upstream interface: " + upstreamIface, interfaceParams);
+ verify(mBpfCoordinator).updateAllIpv6Rules(
+ mIpServer, TEST_IFACE_PARAMS, interfaceParams.index);
+ verifyStartUpstreamIpv6Forwarding(null, interfaceParams.index);
+ } else {
+ verifyNoUpstreamIpv6ForwardingChange(null);
+ }
}
- reset(mNetd, mCallback, mAddressCoordinator, mBpfCoordinator);
+ reset(mCallback, mAddressCoordinator);
+ resetNetdBpfMapAndCoordinator();
when(mAddressCoordinator.requestDownstreamAddress(any(), anyInt(),
anyBoolean())).thenReturn(mTestAddress);
}
@@ -531,7 +542,7 @@
InOrder inOrder = inOrder(mNetd, mBpfCoordinator);
// Add the forwarding pair <IFACE_NAME, UPSTREAM_IFACE>.
- inOrder.verify(mBpfCoordinator).addUpstreamNameToLookupTable(UPSTREAM_IFINDEX,
+ inOrder.verify(mBpfCoordinator).maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX,
UPSTREAM_IFACE);
inOrder.verify(mBpfCoordinator).maybeAttachProgram(IFACE_NAME, UPSTREAM_IFACE);
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE);
@@ -553,7 +564,7 @@
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
// Add the forwarding pair <IFACE_NAME, UPSTREAM_IFACE2>.
- inOrder.verify(mBpfCoordinator).addUpstreamNameToLookupTable(UPSTREAM_IFINDEX2,
+ inOrder.verify(mBpfCoordinator).maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX2,
UPSTREAM_IFACE2);
inOrder.verify(mBpfCoordinator).maybeAttachProgram(IFACE_NAME, UPSTREAM_IFACE2);
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
@@ -578,7 +589,7 @@
// Add the forwarding pair <IFACE_NAME, UPSTREAM_IFACE2> and expect that failed on
// tetherAddForward.
- inOrder.verify(mBpfCoordinator).addUpstreamNameToLookupTable(UPSTREAM_IFINDEX2,
+ inOrder.verify(mBpfCoordinator).maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX2,
UPSTREAM_IFACE2);
inOrder.verify(mBpfCoordinator).maybeAttachProgram(IFACE_NAME, UPSTREAM_IFACE2);
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
@@ -606,7 +617,7 @@
// Add the forwarding pair <IFACE_NAME, UPSTREAM_IFACE2> and expect that failed on
// ipfwdAddInterfaceForward.
- inOrder.verify(mBpfCoordinator).addUpstreamNameToLookupTable(UPSTREAM_IFINDEX2,
+ inOrder.verify(mBpfCoordinator).maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX2,
UPSTREAM_IFACE2);
inOrder.verify(mBpfCoordinator).maybeAttachProgram(IFACE_NAME, UPSTREAM_IFACE2);
inOrder.verify(mNetd).tetherAddForward(IFACE_NAME, UPSTREAM_IFACE2);
@@ -627,7 +638,15 @@
inOrder.verify(mBpfCoordinator).maybeDetachProgram(IFACE_NAME, UPSTREAM_IFACE);
inOrder.verify(mNetd).ipfwdRemoveInterfaceForward(IFACE_NAME, UPSTREAM_IFACE);
inOrder.verify(mNetd).tetherRemoveForward(IFACE_NAME, UPSTREAM_IFACE);
- inOrder.verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
+ inOrder.verify(mBpfCoordinator).updateAllIpv6Rules(
+ mIpServer, TEST_IFACE_PARAMS, NO_UPSTREAM);
+ if (!mBpfDeps.isAtLeastS()) {
+ inOrder.verify(mNetd).tetherOffloadGetAndClearStats(UPSTREAM_IFINDEX);
+ }
+ // When tethering stops, upstream interface is set to zero and thus clearing all upstream
+ // rules. Downstream rules are needed to be cleared explicitly by calling
+ // BpfCoordinator#clearAllIpv6Rules in TetheredState#exit.
+ inOrder.verify(mBpfCoordinator).clearAllIpv6Rules(mIpServer);
inOrder.verify(mNetd).tetherApplyDnsInterfaces();
inOrder.verify(mNetd).tetherInterfaceRemove(IFACE_NAME);
inOrder.verify(mNetd).networkRemoveInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
@@ -1064,13 +1083,12 @@
recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, macA);
verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
- // Events on this interface are received and sent to netd.
+ // Events on this interface are received and sent to BpfCoordinator.
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
verify(mBpfCoordinator).addIpv6DownstreamRule(
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macA));
verifyTetherOffloadRuleAdd(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
- verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
resetNetdBpfMapAndCoordinator();
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
@@ -1078,7 +1096,6 @@
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macB));
verifyTetherOffloadRuleAdd(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
- verifyNoUpstreamIpv6ForwardingChange(null);
resetNetdBpfMapAndCoordinator();
// Link-local and multicast neighbors are ignored.
@@ -1094,7 +1111,6 @@
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macNull));
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macNull);
- verifyNoUpstreamIpv6ForwardingChange(null);
resetNetdBpfMapAndCoordinator();
// A neighbor that is deleted causes the rule to be removed.
@@ -1103,12 +1119,10 @@
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macNull));
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macNull);
- verifyStopUpstreamIpv6Forwarding(null);
resetNetdBpfMapAndCoordinator();
// Upstream changes result in updating the rules.
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
- verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
resetNetdBpfMapAndCoordinator();
@@ -1116,89 +1130,100 @@
LinkProperties lp = new LinkProperties();
lp.setInterfaceName(UPSTREAM_IFACE2);
dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp, -1);
- verify(mBpfCoordinator).tetherOffloadRuleUpdate(mIpServer, UPSTREAM_IFINDEX2);
+ verify(mBpfCoordinator).updateAllIpv6Rules(mIpServer, TEST_IFACE_PARAMS, UPSTREAM_IFINDEX2);
verifyTetherOffloadRuleRemove(inOrder,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
verifyTetherOffloadRuleRemove(inOrder,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
verifyStopUpstreamIpv6Forwarding(inOrder);
- verifyTetherOffloadRuleAdd(inOrder,
- UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
verifyStartUpstreamIpv6Forwarding(inOrder, UPSTREAM_IFINDEX2);
verifyTetherOffloadRuleAdd(inOrder,
+ UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
+ verifyTetherOffloadRuleAdd(inOrder,
UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
- verifyNoUpstreamIpv6ForwardingChange(inOrder);
resetNetdBpfMapAndCoordinator();
// When the upstream is lost, rules are removed.
dispatchTetherConnectionChanged(null, null, 0);
- // Clear function is called two times by:
+ // Upstream clear function is called two times by:
// - processMessage CMD_TETHER_CONNECTION_CHANGED for the upstream is lost.
// - processMessage CMD_IPV6_TETHER_UPDATE for the IPv6 upstream is lost.
// See dispatchTetherConnectionChanged.
- verify(mBpfCoordinator, times(2)).tetherOffloadRuleClear(mIpServer);
+ verify(mBpfCoordinator, times(2)).updateAllIpv6Rules(
+ mIpServer, TEST_IFACE_PARAMS, NO_UPSTREAM);
+ verifyStopUpstreamIpv6Forwarding(inOrder);
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
- verifyStopUpstreamIpv6Forwarding(inOrder);
+ // Upstream lost doesn't clear the downstream rules from BpfCoordinator.
+ // Do that here.
+ recvDelNeigh(myIfindex, neighA, NUD_STALE, macA);
+ recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
+ verify(mBpfCoordinator).removeIpv6DownstreamRule(
+ mIpServer, makeDownstreamRule(NO_UPSTREAM, neighA, macNull));
+ verify(mBpfCoordinator).removeIpv6DownstreamRule(
+ mIpServer, makeDownstreamRule(NO_UPSTREAM, neighB, macNull));
resetNetdBpfMapAndCoordinator();
- // If the upstream is IPv4-only, no rules are added.
+ // If the upstream is IPv4-only, no IPv6 rules are added to BPF map.
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
resetNetdBpfMapAndCoordinator();
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
- // Clear function is called by #updateIpv6ForwardingRules for the IPv6 upstream is lost.
- verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
verifyNoUpstreamIpv6ForwardingChange(null);
+ // Downstream rules are only added to BpfCoordinator but not BPF map.
+ verify(mBpfCoordinator).addIpv6DownstreamRule(
+ mIpServer, makeDownstreamRule(NO_UPSTREAM, neighA, macA));
+ verifyNeverTetherOffloadRuleAdd();
verifyNoMoreInteractions(mBpfCoordinator, mNetd, mBpfDownstream6Map, mBpfUpstream6Map);
- // Rules can be added again once upstream IPv6 connectivity is available.
+ // Rules can be added again once upstream IPv6 connectivity is available. The existing rules
+ // with an upstream of NO_UPSTREAM are reapplied.
lp.setInterfaceName(UPSTREAM_IFACE);
dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
+ verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
+ verify(mBpfCoordinator).addIpv6DownstreamRule(
+ mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macA));
+ verifyTetherOffloadRuleAdd(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
verify(mBpfCoordinator).addIpv6DownstreamRule(
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macB));
verifyTetherOffloadRuleAdd(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
- verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
- verify(mBpfCoordinator, never()).addIpv6DownstreamRule(
- mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macA));
- verifyNeverTetherOffloadRuleAdd(
- UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
// If upstream IPv6 connectivity is lost, rules are removed.
resetNetdBpfMapAndCoordinator();
dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
- verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
+ verify(mBpfCoordinator).updateAllIpv6Rules(mIpServer, TEST_IFACE_PARAMS, NO_UPSTREAM);
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
verifyStopUpstreamIpv6Forwarding(null);
- // When the interface goes down, rules are removed.
+ // When upstream IPv6 connectivity comes back, upstream rules are added and downstream rules
+ // are reapplied.
lp.setInterfaceName(UPSTREAM_IFACE);
dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp, -1);
- recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
- recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
+ verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
verify(mBpfCoordinator).addIpv6DownstreamRule(
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighA, macA));
verifyTetherOffloadRuleAdd(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
- verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
verify(mBpfCoordinator).addIpv6DownstreamRule(
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neighB, macB));
verifyTetherOffloadRuleAdd(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
resetNetdBpfMapAndCoordinator();
+ // When the downstream interface goes down, rules are removed.
mIpServer.stop();
mLooper.dispatchAll();
- verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
+ verify(mBpfCoordinator).clearAllIpv6Rules(mIpServer);
+ verifyStopUpstreamIpv6Forwarding(null);
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
- verifyStopUpstreamIpv6Forwarding(null);
verify(mIpNeighborMonitor).stop();
resetNetdBpfMapAndCoordinator();
}
@@ -1228,7 +1253,6 @@
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neigh, macA));
verifyTetherOffloadRuleAdd(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neigh, macA);
- verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
resetNetdBpfMapAndCoordinator();
recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
@@ -1236,7 +1260,14 @@
mIpServer, makeDownstreamRule(UPSTREAM_IFINDEX, neigh, macNull));
verifyTetherOffloadRuleRemove(null,
UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neigh, macNull);
- verifyStopUpstreamIpv6Forwarding(null);
+ resetNetdBpfMapAndCoordinator();
+
+ // Upstream IPv6 connectivity change causes upstream rules change.
+ LinkProperties lp2 = new LinkProperties();
+ lp2.setInterfaceName(UPSTREAM_IFACE2);
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp2, 0);
+ verify(mBpfCoordinator).updateAllIpv6Rules(mIpServer, TEST_IFACE_PARAMS, UPSTREAM_IFINDEX2);
+ verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX2);
resetNetdBpfMapAndCoordinator();
// [2] Disable BPF offload.
@@ -1247,12 +1278,16 @@
recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
verifyNeverTetherOffloadRuleAdd();
- verifyNoUpstreamIpv6ForwardingChange(null);
resetNetdBpfMapAndCoordinator();
recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
verifyNeverTetherOffloadRuleRemove();
+ resetNetdBpfMapAndCoordinator();
+
+ // Upstream IPv6 connectivity change doesn't cause the rule to be added or removed.
+ dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp2, 0);
verifyNoUpstreamIpv6ForwardingChange(null);
+ verifyNeverTetherOffloadRuleRemove();
resetNetdBpfMapAndCoordinator();
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 04eb430..601f587 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -169,6 +169,8 @@
private static final String UPSTREAM_IFACE = "rmnet0";
private static final String UPSTREAM_XLAT_IFACE = "v4-rmnet0";
private static final String UPSTREAM_IFACE2 = "wlan0";
+ private static final String DOWNSTREAM_IFACE = "downstream1";
+ private static final String DOWNSTREAM_IFACE2 = "downstream2";
private static final MacAddress DOWNSTREAM_MAC = MacAddress.fromString("12:34:56:78:90:ab");
private static final MacAddress DOWNSTREAM_MAC2 = MacAddress.fromString("ab:90:78:56:34:12");
@@ -213,6 +215,11 @@
private static final InterfaceParams UPSTREAM_IFACE_PARAMS2 = new InterfaceParams(
UPSTREAM_IFACE2, UPSTREAM_IFINDEX2, MacAddress.fromString("44:55:66:00:00:0c"),
NetworkStackConstants.ETHER_MTU);
+ private static final InterfaceParams DOWNSTREAM_IFACE_PARAMS = new InterfaceParams(
+ DOWNSTREAM_IFACE, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC, NetworkStackConstants.ETHER_MTU);
+ private static final InterfaceParams DOWNSTREAM_IFACE_PARAMS2 = new InterfaceParams(
+ DOWNSTREAM_IFACE2, DOWNSTREAM_IFINDEX2, DOWNSTREAM_MAC2,
+ NetworkStackConstants.ETHER_MTU);
private static final Map<Integer, UpstreamInformation> UPSTREAM_INFORMATIONS = Map.of(
UPSTREAM_IFINDEX, new UpstreamInformation(UPSTREAM_IFACE_PARAMS,
@@ -640,24 +647,6 @@
}
}
- private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex,
- MacAddress downstreamMac, int upstreamIfindex) throws Exception {
- if (!mDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac, 0);
- final Tether6Value value = new Tether6Value(upstreamIfindex,
- MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
- ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
- verifyWithOrder(inOrder, mBpfUpstream6Map).insertEntry(key, value);
- }
-
- private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex,
- MacAddress downstreamMac)
- throws Exception {
- if (!mDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac, 0);
- verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
- }
-
private void verifyNoUpstreamIpv6ForwardingChange(@Nullable InOrder inOrder) throws Exception {
if (!mDeps.isAtLeastS()) return;
if (inOrder != null) {
@@ -671,6 +660,13 @@
}
}
+ private void verifyAddUpstreamRule(@Nullable InOrder inOrder,
+ @NonNull Ipv6UpstreamRule rule) throws Exception {
+ if (!mDeps.isAtLeastS()) return;
+ verifyWithOrder(inOrder, mBpfUpstream6Map).insertEntry(
+ rule.makeTetherUpstream6Key(), rule.makeTether6Value());
+ }
+
private void verifyAddDownstreamRule(@Nullable InOrder inOrder,
@NonNull Ipv6DownstreamRule rule) throws Exception {
if (mDeps.isAtLeastS()) {
@@ -681,6 +677,11 @@
}
}
+ private void verifyNeverAddUpstreamRule() throws Exception {
+ if (!mDeps.isAtLeastS()) return;
+ verify(mBpfUpstream6Map, never()).insertEntry(any(), any());
+ }
+
private void verifyNeverAddDownstreamRule() throws Exception {
if (mDeps.isAtLeastS()) {
verify(mBpfDownstream6Map, never()).updateEntry(any(), any());
@@ -689,6 +690,13 @@
}
}
+ private void verifyRemoveUpstreamRule(@Nullable InOrder inOrder,
+ @NonNull final Ipv6UpstreamRule rule) throws Exception {
+ if (!mDeps.isAtLeastS()) return;
+ verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(
+ rule.makeTetherUpstream6Key());
+ }
+
private void verifyRemoveDownstreamRule(@Nullable InOrder inOrder,
@NonNull final Ipv6DownstreamRule rule) throws Exception {
if (mDeps.isAtLeastS()) {
@@ -699,6 +707,11 @@
}
}
+ private void verifyNeverRemoveUpstreamRule() throws Exception {
+ if (!mDeps.isAtLeastS()) return;
+ verify(mBpfUpstream6Map, never()).deleteEntry(any());
+ }
+
private void verifyNeverRemoveDownstreamRule() throws Exception {
if (mDeps.isAtLeastS()) {
verify(mBpfDownstream6Map, never()).deleteEntry(any());
@@ -763,24 +776,31 @@
final String mobileIface = "rmnet_data0";
final Integer mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+ coordinator.maybeAddUpstreamToLookupTable(mobileIfIndex, mobileIface);
// InOrder is required because mBpfStatsMap may be accessed by both
// BpfCoordinator#tetherOffloadRuleAdd and BpfCoordinator#tetherOffloadGetAndClearStats.
// The #verifyTetherOffloadGetAndClearStats can't distinguish who has ever called
// mBpfStatsMap#getValue and get a wrong calling count which counts all.
- final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfLimitMap, mBpfStatsMap);
- final Ipv6DownstreamRule rule = buildTestDownstreamRule(mobileIfIndex, NEIGH_A, MAC_A);
- coordinator.addIpv6DownstreamRule(mIpServer, rule);
- verifyAddDownstreamRule(inOrder, rule);
+ final InOrder inOrder = inOrder(mNetd, mBpfUpstream6Map, mBpfDownstream6Map, mBpfLimitMap,
+ mBpfStatsMap);
+ final Ipv6UpstreamRule upstreamRule = buildTestUpstreamRule(
+ mobileIfIndex, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
+ final Ipv6DownstreamRule downstreamRule = buildTestDownstreamRule(
+ mobileIfIndex, NEIGH_A, MAC_A);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, mobileIfIndex);
verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, QUOTA_UNLIMITED,
true /* isInit */);
+ verifyAddUpstreamRule(inOrder, upstreamRule);
+ coordinator.addIpv6DownstreamRule(mIpServer, downstreamRule);
+ verifyAddDownstreamRule(inOrder, downstreamRule);
- // Removing the last rule on current upstream immediately sends the cleanup stuff to netd.
+ // Removing the last rule on current upstream immediately sends the cleanup stuff to BPF.
updateStatsEntryForTetherOffloadGetAndClearStats(
buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
- coordinator.removeIpv6DownstreamRule(mIpServer, rule);
- verifyRemoveDownstreamRule(inOrder, rule);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, 0);
+ verifyRemoveDownstreamRule(inOrder, downstreamRule);
+ verifyRemoveUpstreamRule(inOrder, upstreamRule);
verifyTetherOffloadGetAndClearStats(inOrder, mobileIfIndex);
}
@@ -806,7 +826,7 @@
final String mobileIface = "rmnet_data0";
final Integer mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+ coordinator.maybeAddUpstreamToLookupTable(mobileIfIndex, mobileIface);
updateStatsEntriesAndWaitForUpdate(new TetherStatsParcel[] {
buildTestTetherStatsParcel(mobileIfIndex, 1000, 100, 2000, 200)});
@@ -847,8 +867,8 @@
// Add interface name to lookup table. In realistic case, the upstream interface name will
// be added by IpServer when IpServer has received with a new IPv6 upstream update event.
- coordinator.addUpstreamNameToLookupTable(wlanIfIndex, wlanIface);
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+ coordinator.maybeAddUpstreamToLookupTable(wlanIfIndex, wlanIface);
+ coordinator.maybeAddUpstreamToLookupTable(mobileIfIndex, mobileIface);
// [1] Both interface stats are changed.
// Setup the tether stats of wlan and mobile interface. Note that move forward the time of
@@ -912,7 +932,7 @@
final String mobileIface = "rmnet_data0";
final Integer mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+ coordinator.maybeAddUpstreamToLookupTable(mobileIfIndex, mobileIface);
// Verify that set quota to 0 will immediately triggers a callback.
mTetherStatsProvider.onSetAlert(0);
@@ -978,9 +998,10 @@
}
@NonNull
- private static Ipv6UpstreamRule buildTestUpstreamRule(int upstreamIfindex) {
- return new Ipv6UpstreamRule(upstreamIfindex, DOWNSTREAM_IFINDEX,
- IPV6_ZERO_PREFIX, DOWNSTREAM_MAC, MacAddress.ALL_ZEROS_ADDRESS,
+ private static Ipv6UpstreamRule buildTestUpstreamRule(
+ int upstreamIfindex, int downstreamIfindex, @NonNull MacAddress inDstMac) {
+ return new Ipv6UpstreamRule(upstreamIfindex, downstreamIfindex,
+ IPV6_ZERO_PREFIX, inDstMac, MacAddress.ALL_ZEROS_ADDRESS,
MacAddress.ALL_ZEROS_ADDRESS);
}
@@ -1027,17 +1048,18 @@
final String mobileIface = "rmnet_data0";
final int mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+ coordinator.maybeAddUpstreamToLookupTable(mobileIfIndex, mobileIface);
// [1] Default limit.
// Set the unlimited quota as default if the service has never applied a data limit for a
// given upstream. Note that the data limit only be applied on an upstream which has rules.
- final Ipv6DownstreamRule rule = buildTestDownstreamRule(mobileIfIndex, NEIGH_A, MAC_A);
- final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfLimitMap, mBpfStatsMap);
- coordinator.addIpv6DownstreamRule(mIpServer, rule);
- verifyAddDownstreamRule(inOrder, rule);
+ final Ipv6UpstreamRule rule = buildTestUpstreamRule(
+ mobileIfIndex, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
+ final InOrder inOrder = inOrder(mNetd, mBpfUpstream6Map, mBpfLimitMap, mBpfStatsMap);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, mobileIfIndex);
verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, QUOTA_UNLIMITED,
true /* isInit */);
+ verifyAddUpstreamRule(inOrder, rule);
inOrder.verifyNoMoreInteractions();
// [2] Specific limit.
@@ -1062,7 +1084,6 @@
}
}
- // TODO: Test the case in which the rules are changed from different IpServer objects.
@Test
public void testSetDataLimitOnRule6Change() throws Exception {
setupFunctioningNetdInterface();
@@ -1071,39 +1092,41 @@
final String mobileIface = "rmnet_data0";
final int mobileIfIndex = 100;
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+ coordinator.maybeAddUpstreamToLookupTable(mobileIfIndex, mobileIface);
// Applying a data limit to the current upstream does not take any immediate action.
// The data limit could be only set on an upstream which has rules.
final long limit = 12345;
- final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfLimitMap, mBpfStatsMap);
+ final InOrder inOrder = inOrder(mNetd, mBpfUpstream6Map, mBpfLimitMap, mBpfStatsMap);
mTetherStatsProvider.onSetLimit(mobileIface, limit);
waitForIdle();
verifyNeverTetherOffloadSetInterfaceQuota(inOrder);
- // Adding the first rule on current upstream immediately sends the quota to netd.
- final Ipv6DownstreamRule ruleA = buildTestDownstreamRule(mobileIfIndex, NEIGH_A, MAC_A);
- coordinator.addIpv6DownstreamRule(mIpServer, ruleA);
- verifyAddDownstreamRule(inOrder, ruleA);
+ // Adding the first rule on current upstream immediately sends the quota to BPF.
+ final Ipv6UpstreamRule ruleA = buildTestUpstreamRule(
+ mobileIfIndex, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, mobileIfIndex);
verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, limit, true /* isInit */);
+ verifyAddUpstreamRule(inOrder, ruleA);
inOrder.verifyNoMoreInteractions();
- // Adding the second rule on current upstream does not send the quota to netd.
- final Ipv6DownstreamRule ruleB = buildTestDownstreamRule(mobileIfIndex, NEIGH_B, MAC_B);
- coordinator.addIpv6DownstreamRule(mIpServer, ruleB);
- verifyAddDownstreamRule(inOrder, ruleB);
+ // Adding the second rule on current upstream does not send the quota to BPF.
+ final Ipv6UpstreamRule ruleB = buildTestUpstreamRule(
+ mobileIfIndex, DOWNSTREAM_IFINDEX2, DOWNSTREAM_MAC2);
+ coordinator.updateAllIpv6Rules(mIpServer2, DOWNSTREAM_IFACE_PARAMS2, mobileIfIndex);
+ verifyAddUpstreamRule(inOrder, ruleB);
verifyNeverTetherOffloadSetInterfaceQuota(inOrder);
- // Removing the second rule on current upstream does not send the quota to netd.
- coordinator.removeIpv6DownstreamRule(mIpServer, ruleB);
- verifyRemoveDownstreamRule(inOrder, ruleB);
+ // Removing the second rule on current upstream does not send the quota to BPF.
+ coordinator.updateAllIpv6Rules(mIpServer2, DOWNSTREAM_IFACE_PARAMS2, 0);
+ verifyRemoveUpstreamRule(inOrder, ruleB);
verifyNeverTetherOffloadSetInterfaceQuota(inOrder);
- // Removing the last rule on current upstream immediately sends the cleanup stuff to netd.
+ // Removing the last rule on current upstream immediately sends the cleanup stuff to BPF.
updateStatsEntryForTetherOffloadGetAndClearStats(
buildTestTetherStatsParcel(mobileIfIndex, 0, 0, 0, 0));
- coordinator.removeIpv6DownstreamRule(mIpServer, ruleA);
- verifyRemoveDownstreamRule(inOrder, ruleA);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, 0);
+ verifyRemoveUpstreamRule(inOrder, ruleA);
verifyTetherOffloadGetAndClearStats(inOrder, mobileIfIndex);
inOrder.verifyNoMoreInteractions();
}
@@ -1118,8 +1141,8 @@
final String mobileIface = "rmnet_data0";
final Integer ethIfIndex = 100;
final Integer mobileIfIndex = 101;
- coordinator.addUpstreamNameToLookupTable(ethIfIndex, ethIface);
- coordinator.addUpstreamNameToLookupTable(mobileIfIndex, mobileIface);
+ coordinator.maybeAddUpstreamToLookupTable(ethIfIndex, ethIface);
+ coordinator.maybeAddUpstreamToLookupTable(mobileIfIndex, mobileIface);
final InOrder inOrder = inOrder(mNetd, mBpfDownstream6Map, mBpfUpstream6Map, mBpfLimitMap,
mBpfStatsMap);
@@ -1133,20 +1156,25 @@
// [1] Adding rules on the upstream Ethernet.
// Note that the default data limit is applied after the first rule is added.
+ final Ipv6UpstreamRule ethernetUpstreamRule = buildTestUpstreamRule(
+ ethIfIndex, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
final Ipv6DownstreamRule ethernetRuleA = buildTestDownstreamRule(
ethIfIndex, NEIGH_A, MAC_A);
final Ipv6DownstreamRule ethernetRuleB = buildTestDownstreamRule(
ethIfIndex, NEIGH_B, MAC_B);
- coordinator.addIpv6DownstreamRule(mIpServer, ethernetRuleA);
- verifyAddDownstreamRule(inOrder, ethernetRuleA);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, ethIfIndex);
verifyTetherOffloadSetInterfaceQuota(inOrder, ethIfIndex, QUOTA_UNLIMITED,
true /* isInit */);
- verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC, ethIfIndex);
+ verifyAddUpstreamRule(inOrder, ethernetUpstreamRule);
+ coordinator.addIpv6DownstreamRule(mIpServer, ethernetRuleA);
+ verifyAddDownstreamRule(inOrder, ethernetRuleA);
coordinator.addIpv6DownstreamRule(mIpServer, ethernetRuleB);
verifyAddDownstreamRule(inOrder, ethernetRuleB);
// [2] Update the existing rules from Ethernet to cellular.
+ final Ipv6UpstreamRule mobileUpstreamRule = buildTestUpstreamRule(
+ mobileIfIndex, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
final Ipv6DownstreamRule mobileRuleA = buildTestDownstreamRule(
mobileIfIndex, NEIGH_A, MAC_A);
final Ipv6DownstreamRule mobileRuleB = buildTestDownstreamRule(
@@ -1156,25 +1184,24 @@
// Update the existing rules for upstream changes. The rules are removed and re-added one
// by one for updating upstream interface index by #tetherOffloadRuleUpdate.
- coordinator.tetherOffloadRuleUpdate(mIpServer, mobileIfIndex);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, mobileIfIndex);
verifyRemoveDownstreamRule(inOrder, ethernetRuleA);
verifyRemoveDownstreamRule(inOrder, ethernetRuleB);
- verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
+ verifyRemoveUpstreamRule(inOrder, ethernetUpstreamRule);
verifyTetherOffloadGetAndClearStats(inOrder, ethIfIndex);
- verifyAddDownstreamRule(inOrder, mobileRuleA);
verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, QUOTA_UNLIMITED,
true /* isInit */);
- verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC,
- mobileIfIndex);
+ verifyAddUpstreamRule(inOrder, mobileUpstreamRule);
+ verifyAddDownstreamRule(inOrder, mobileRuleA);
verifyAddDownstreamRule(inOrder, mobileRuleB);
// [3] Clear all rules for a given IpServer.
updateStatsEntryForTetherOffloadGetAndClearStats(
buildTestTetherStatsParcel(mobileIfIndex, 50, 60, 70, 80));
- coordinator.tetherOffloadRuleClear(mIpServer);
+ coordinator.clearAllIpv6Rules(mIpServer);
verifyRemoveDownstreamRule(inOrder, mobileRuleA);
verifyRemoveDownstreamRule(inOrder, mobileRuleB);
- verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
+ verifyRemoveUpstreamRule(inOrder, mobileUpstreamRule);
verifyTetherOffloadGetAndClearStats(inOrder, mobileIfIndex);
// [4] Force pushing stats update to verify that the last diff of stats is reported on all
@@ -1204,7 +1231,7 @@
// The interface name lookup table can't be added.
final String iface = "rmnet_data0";
final Integer ifIndex = 100;
- coordinator.addUpstreamNameToLookupTable(ifIndex, iface);
+ coordinator.maybeAddUpstreamToLookupTable(ifIndex, iface);
assertEquals(0, coordinator.getInterfaceNamesForTesting().size());
// The rule can't be added.
@@ -1230,14 +1257,15 @@
assertEquals(1, rules.size());
// The rule can't be cleared.
- coordinator.tetherOffloadRuleClear(mIpServer);
+ coordinator.clearAllIpv6Rules(mIpServer);
verifyNeverRemoveDownstreamRule();
rules = coordinator.getIpv6DownstreamRulesForTesting().get(mIpServer);
assertNotNull(rules);
assertEquals(1, rules.size());
// The rule can't be updated.
- coordinator.tetherOffloadRuleUpdate(mIpServer, rule.upstreamIfindex + 1 /* new */);
+ coordinator.updateAllIpv6Rules(
+ mIpServer, DOWNSTREAM_IFACE_PARAMS, rule.upstreamIfindex + 1 /* new */);
verifyNeverRemoveDownstreamRule();
verifyNeverAddDownstreamRule();
rules = coordinator.getIpv6DownstreamRulesForTesting().get(mIpServer);
@@ -1552,7 +1580,7 @@
// interface index.
doReturn(upstreamInfo.interfaceParams).when(mDeps).getInterfaceParams(
upstreamInfo.interfaceParams.name);
- coordinator.addUpstreamNameToLookupTable(upstreamInfo.interfaceParams.index,
+ coordinator.maybeAddUpstreamToLookupTable(upstreamInfo.interfaceParams.index,
upstreamInfo.interfaceParams.name);
final LinkProperties lp = new LinkProperties();
@@ -1677,19 +1705,21 @@
public void testAddDevMapRule6() throws Exception {
final BpfCoordinator coordinator = makeBpfCoordinator();
- coordinator.addUpstreamNameToLookupTable(UPSTREAM_IFINDEX, UPSTREAM_IFACE);
- final Ipv6DownstreamRule ruleA = buildTestDownstreamRule(UPSTREAM_IFINDEX, NEIGH_A, MAC_A);
- final Ipv6DownstreamRule ruleB = buildTestDownstreamRule(UPSTREAM_IFINDEX, NEIGH_B, MAC_B);
-
- coordinator.addIpv6DownstreamRule(mIpServer, ruleA);
+ coordinator.maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX, UPSTREAM_IFACE);
+ coordinator.updateAllIpv6Rules(mIpServer, DOWNSTREAM_IFACE_PARAMS, UPSTREAM_IFINDEX);
verify(mBpfDevMap).updateEntry(eq(new TetherDevKey(UPSTREAM_IFINDEX)),
eq(new TetherDevValue(UPSTREAM_IFINDEX)));
verify(mBpfDevMap).updateEntry(eq(new TetherDevKey(DOWNSTREAM_IFINDEX)),
eq(new TetherDevValue(DOWNSTREAM_IFINDEX)));
clearInvocations(mBpfDevMap);
- coordinator.addIpv6DownstreamRule(mIpServer, ruleB);
- verify(mBpfDevMap, never()).updateEntry(any(), any());
+ // Adding the second downstream, only the second downstream ifindex is added to DevMap,
+ // the existing upstream ifindex won't be added again.
+ coordinator.updateAllIpv6Rules(mIpServer2, DOWNSTREAM_IFACE_PARAMS2, UPSTREAM_IFINDEX);
+ verify(mBpfDevMap).updateEntry(eq(new TetherDevKey(DOWNSTREAM_IFINDEX2)),
+ eq(new TetherDevValue(DOWNSTREAM_IFINDEX2)));
+ verify(mBpfDevMap, never()).updateEntry(eq(new TetherDevKey(UPSTREAM_IFINDEX)),
+ eq(new TetherDevValue(UPSTREAM_IFINDEX)));
}
@Test
@@ -2153,7 +2183,8 @@
assertEquals("upstreamIfindex: 1001, downstreamIfindex: 2001, address: 2001:db8::1, "
+ "srcMac: 12:34:56:78:90:ab, dstMac: 00:00:00:00:00:0a",
downstreamRule.toString());
- final Ipv6UpstreamRule upstreamRule = buildTestUpstreamRule(UPSTREAM_IFINDEX);
+ final Ipv6UpstreamRule upstreamRule = buildTestUpstreamRule(
+ UPSTREAM_IFINDEX, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
assertEquals("upstreamIfindex: 1001, downstreamIfindex: 2001, sourcePrefix: ::/64, "
+ "inDstMac: 12:34:56:78:90:ab, outSrcMac: 00:00:00:00:00:00, "
+ "outDstMac: 00:00:00:00:00:00", upstreamRule.toString());
@@ -2221,7 +2252,7 @@
0L /* txPackets */, 0L /* txBytes */, 0L /* txErrors */));
// dumpDevmap
- coordinator.addUpstreamNameToLookupTable(UPSTREAM_IFINDEX, UPSTREAM_IFACE);
+ coordinator.maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX, UPSTREAM_IFACE);
mBpfDevMap.insertEntry(
new TetherDevKey(UPSTREAM_IFINDEX),
new TetherDevValue(UPSTREAM_IFINDEX));
@@ -2390,7 +2421,7 @@
// +-------+-------+-------+-------+-------+
// [1] Mobile IPv4 only
- coordinator.addUpstreamNameToLookupTable(UPSTREAM_IFINDEX, UPSTREAM_IFACE);
+ coordinator.maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX, UPSTREAM_IFACE);
doReturn(UPSTREAM_IFACE_PARAMS).when(mDeps).getInterfaceParams(UPSTREAM_IFACE);
final UpstreamNetworkState mobileIPv4UpstreamState = new UpstreamNetworkState(
buildUpstreamLinkProperties(UPSTREAM_IFACE,
@@ -2442,7 +2473,7 @@
verifyIpv4Upstream(ipv4UpstreamIndices, interfaceNames);
// Mobile IPv6 and xlat
- // IpServer doesn't add xlat interface mapping via #addUpstreamNameToLookupTable on
+ // IpServer doesn't add xlat interface mapping via #maybeAddUpstreamToLookupTable on
// S and T devices.
coordinator.updateUpstreamNetworkState(mobile464xlatUpstreamState);
// Upstream IPv4 address mapping is removed because xlat interface is not supported.
@@ -2457,7 +2488,7 @@
// [6] Wifi IPv4 and IPv6
// Expect that upstream index map is cleared because ether ip is not supported.
- coordinator.addUpstreamNameToLookupTable(UPSTREAM_IFINDEX2, UPSTREAM_IFACE2);
+ coordinator.maybeAddUpstreamToLookupTable(UPSTREAM_IFINDEX2, UPSTREAM_IFACE2);
doReturn(UPSTREAM_IFACE_PARAMS2).when(mDeps).getInterfaceParams(UPSTREAM_IFACE2);
final UpstreamNetworkState wifiDualStackUpstreamState = new UpstreamNetworkState(
buildUpstreamLinkProperties(UPSTREAM_IFACE2,
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index 0054d4a..256dd6a 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -89,11 +89,11 @@
DEFINE_BPF_MAP_RW_NETD(cookie_tag_map, HASH, uint64_t, UidTagValue, COOKIE_UID_MAP_SIZE)
DEFINE_BPF_MAP_NO_NETD(uid_counterset_map, HASH, uint32_t, uint8_t, UID_COUNTERSET_MAP_SIZE)
DEFINE_BPF_MAP_NO_NETD(app_uid_stats_map, HASH, uint32_t, StatsValue, APP_STATS_MAP_SIZE)
-DEFINE_BPF_MAP_RW_NETD(stats_map_A, HASH, StatsKey, StatsValue, STATS_MAP_SIZE)
+DEFINE_BPF_MAP_RO_NETD(stats_map_A, HASH, StatsKey, StatsValue, STATS_MAP_SIZE)
DEFINE_BPF_MAP_RO_NETD(stats_map_B, HASH, StatsKey, StatsValue, STATS_MAP_SIZE)
DEFINE_BPF_MAP_NO_NETD(iface_stats_map, HASH, uint32_t, StatsValue, IFACE_STATS_MAP_SIZE)
DEFINE_BPF_MAP_NO_NETD(uid_owner_map, HASH, uint32_t, UidOwnerValue, UID_OWNER_MAP_SIZE)
-DEFINE_BPF_MAP_RW_NETD(uid_permission_map, HASH, uint32_t, uint8_t, UID_OWNER_MAP_SIZE)
+DEFINE_BPF_MAP_RO_NETD(uid_permission_map, HASH, uint32_t, uint8_t, UID_OWNER_MAP_SIZE)
DEFINE_BPF_MAP_NO_NETD(ingress_discard_map, HASH, IngressDiscardKey, IngressDiscardValue,
INGRESS_DISCARD_MAP_SIZE)
@@ -104,14 +104,13 @@
DEFINE_BPF_MAP_EXT(packet_trace_enabled_map, ARRAY, uint32_t, bool, 1,
AID_ROOT, AID_SYSTEM, 0060, "fs_bpf_net_shared", "", false,
BPFLOADER_IGNORED_ON_VERSION, BPFLOADER_MAX_VER, LOAD_ON_ENG,
- IGNORE_ON_USER, LOAD_ON_USERDEBUG)
+ LOAD_ON_USER, LOAD_ON_USERDEBUG)
-// A ring buffer on which packet information is pushed. This map will only be loaded
-// on eng and userdebug devices. User devices won't load this to save memory.
+// A ring buffer on which packet information is pushed.
DEFINE_BPF_RINGBUF_EXT(packet_trace_ringbuf, PacketTrace, PACKET_TRACE_BUF_SIZE,
AID_ROOT, AID_SYSTEM, 0060, "fs_bpf_net_shared", "", false,
BPFLOADER_IGNORED_ON_VERSION, BPFLOADER_MAX_VER, LOAD_ON_ENG,
- IGNORE_ON_USER, LOAD_ON_USERDEBUG);
+ LOAD_ON_USER, LOAD_ON_USERDEBUG);
// iptables xt_bpf programs need to be usable by both netd and netutils_wrappers
// selinux contexts, because even non-xt_bpf iptables mutations are implemented as
@@ -504,6 +503,16 @@
return match;
}
+// This program is optional, and enables tracing on Android U+, 5.8+ on user builds.
+DEFINE_BPF_PROG_EXT("cgroupskb/ingress/stats$trace_user", AID_ROOT, AID_SYSTEM,
+ bpf_cgroup_ingress_trace_user, KVER(5, 8, 0), KVER_INF,
+ BPFLOADER_IGNORED_ON_VERSION, BPFLOADER_MAX_VER, true,
+ "fs_bpf_netd_readonly", "", true, false, true)
+(struct __sk_buff* skb) {
+ return bpf_traffic_account(skb, INGRESS, TRACE_ON, KVER(5, 8, 0));
+}
+
+// This program is required, and enables tracing on Android U+, 5.8+, userdebug/eng.
DEFINE_BPF_PROG_EXT("cgroupskb/ingress/stats$trace", AID_ROOT, AID_SYSTEM,
bpf_cgroup_ingress_trace, KVER(5, 8, 0), KVER_INF,
BPFLOADER_IGNORED_ON_VERSION, BPFLOADER_MAX_VER, false,
@@ -524,6 +533,16 @@
return bpf_traffic_account(skb, INGRESS, TRACE_OFF, KVER_NONE);
}
+// This program is optional, and enables tracing on Android U+, 5.8+ on user builds.
+DEFINE_BPF_PROG_EXT("cgroupskb/egress/stats$trace_user", AID_ROOT, AID_SYSTEM,
+ bpf_cgroup_egress_trace_user, KVER(5, 8, 0), KVER_INF,
+ BPFLOADER_IGNORED_ON_VERSION, BPFLOADER_MAX_VER, true,
+ "fs_bpf_netd_readonly", "", true, false, true)
+(struct __sk_buff* skb) {
+ return bpf_traffic_account(skb, EGRESS, TRACE_ON, KVER(5, 8, 0));
+}
+
+// This program is required, and enables tracing on Android U+, 5.8+, userdebug/eng.
DEFINE_BPF_PROG_EXT("cgroupskb/egress/stats$trace", AID_ROOT, AID_SYSTEM,
bpf_cgroup_egress_trace, KVER(5, 8, 0), KVER_INF,
BPFLOADER_IGNORED_ON_VERSION, BPFLOADER_MAX_VER, false,
diff --git a/framework-t/api/OWNERS b/framework-t/api/OWNERS
index af583c3..607f85a 100644
--- a/framework-t/api/OWNERS
+++ b/framework-t/api/OWNERS
@@ -1,2 +1,2 @@
-file:platform/packages/modules/Connectivity:master:/nearby/OWNERS
-file:platform/packages/modules/Connectivity:master:/remoteauth/OWNERS
+file:platform/packages/modules/Connectivity:main:/nearby/OWNERS
+file:platform/packages/modules/Connectivity:main:/remoteauth/OWNERS
diff --git a/framework-t/udc-extended-api/OWNERS b/framework-t/udc-extended-api/OWNERS
index af583c3..607f85a 100644
--- a/framework-t/udc-extended-api/OWNERS
+++ b/framework-t/udc-extended-api/OWNERS
@@ -1,2 +1,2 @@
-file:platform/packages/modules/Connectivity:master:/nearby/OWNERS
-file:platform/packages/modules/Connectivity:master:/remoteauth/OWNERS
+file:platform/packages/modules/Connectivity:main:/nearby/OWNERS
+file:platform/packages/modules/Connectivity:main:/remoteauth/OWNERS
diff --git a/framework/cronet_disabled/api/current.txt b/framework/cronet_disabled/api/current.txt
deleted file mode 100644
index 672e3e2..0000000
--- a/framework/cronet_disabled/api/current.txt
+++ /dev/null
@@ -1,527 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public class CaptivePortal implements android.os.Parcelable {
- method public int describeContents();
- method public void ignoreNetwork();
- method public void reportCaptivePortalDismissed();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortal> CREATOR;
- }
-
- public class ConnectivityDiagnosticsManager {
- method public void registerConnectivityDiagnosticsCallback(@NonNull android.net.NetworkRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
- method public void unregisterConnectivityDiagnosticsCallback(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
- }
-
- public abstract static class ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback {
- ctor public ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback();
- method public void onConnectivityReportAvailable(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport);
- method public void onDataStallSuspected(@NonNull android.net.ConnectivityDiagnosticsManager.DataStallReport);
- method public void onNetworkConnectivityReported(@NonNull android.net.Network, boolean);
- }
-
- public static final class ConnectivityDiagnosticsManager.ConnectivityReport implements android.os.Parcelable {
- ctor public ConnectivityDiagnosticsManager.ConnectivityReport(@NonNull android.net.Network, long, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
- method public int describeContents();
- method @NonNull public android.os.PersistableBundle getAdditionalInfo();
- method @NonNull public android.net.LinkProperties getLinkProperties();
- method @NonNull public android.net.Network getNetwork();
- method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
- method public long getReportTimestamp();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.ConnectivityReport> CREATOR;
- field public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK = "networkProbesAttempted";
- field public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK = "networkProbesSucceeded";
- field public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult";
- field public static final int NETWORK_PROBE_DNS = 4; // 0x4
- field public static final int NETWORK_PROBE_FALLBACK = 32; // 0x20
- field public static final int NETWORK_PROBE_HTTP = 8; // 0x8
- field public static final int NETWORK_PROBE_HTTPS = 16; // 0x10
- field public static final int NETWORK_PROBE_PRIVATE_DNS = 64; // 0x40
- field public static final int NETWORK_VALIDATION_RESULT_INVALID = 0; // 0x0
- field public static final int NETWORK_VALIDATION_RESULT_PARTIALLY_VALID = 2; // 0x2
- field public static final int NETWORK_VALIDATION_RESULT_SKIPPED = 3; // 0x3
- field public static final int NETWORK_VALIDATION_RESULT_VALID = 1; // 0x1
- }
-
- public static final class ConnectivityDiagnosticsManager.DataStallReport implements android.os.Parcelable {
- ctor public ConnectivityDiagnosticsManager.DataStallReport(@NonNull android.net.Network, long, int, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
- method public int describeContents();
- method public int getDetectionMethod();
- method @NonNull public android.net.LinkProperties getLinkProperties();
- method @NonNull public android.net.Network getNetwork();
- method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
- method public long getReportTimestamp();
- method @NonNull public android.os.PersistableBundle getStallDetails();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.DataStallReport> CREATOR;
- field public static final int DETECTION_METHOD_DNS_EVENTS = 1; // 0x1
- field public static final int DETECTION_METHOD_TCP_METRICS = 2; // 0x2
- field public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS = "dnsConsecutiveTimeouts";
- field public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS = "tcpMetricsCollectionPeriodMillis";
- field public static final String KEY_TCP_PACKET_FAIL_RATE = "tcpPacketFailRate";
- }
-
- public class ConnectivityManager {
- method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
- method public boolean bindProcessToNetwork(@Nullable android.net.Network);
- method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
- method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
- method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
- method @Deprecated public boolean getBackgroundDataSetting();
- method @Nullable public android.net.Network getBoundNetworkForProcess();
- method public int getConnectionOwnerUid(int, @NonNull java.net.InetSocketAddress, @NonNull java.net.InetSocketAddress);
- method @Nullable public android.net.ProxyInfo getDefaultProxy();
- method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.LinkProperties getLinkProperties(@Nullable android.net.Network);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getMultipathPreference(@Nullable android.net.Network);
- method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkCapabilities getNetworkCapabilities(@Nullable android.net.Network);
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(int);
- method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(@Nullable android.net.Network);
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getNetworkPreference();
- method @Nullable public byte[] getNetworkWatchlistConfigHash();
- method @Deprecated @Nullable public static android.net.Network getProcessDefaultNetwork();
- method public int getRestrictBackgroundStatus();
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public boolean isActiveNetworkMetered();
- method public boolean isDefaultNetworkActive();
- method @Deprecated public static boolean isNetworkTypeValid(int);
- method public void registerBestMatchingNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
- method public void releaseNetworkRequest(@NonNull android.app.PendingIntent);
- method public void removeDefaultNetworkActiveListener(@NonNull android.net.ConnectivityManager.OnNetworkActiveListener);
- method @Deprecated public void reportBadNetwork(@Nullable android.net.Network);
- method public void reportNetworkConnectivity(@Nullable android.net.Network, boolean);
- method public boolean requestBandwidthUpdate(@NonNull android.net.Network);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler, int);
- method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
- method @Deprecated public void setNetworkPreference(int);
- method @Deprecated public static boolean setProcessDefaultNetwork(@Nullable android.net.Network);
- method public void unregisterNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
- method public void unregisterNetworkCallback(@NonNull android.app.PendingIntent);
- field @Deprecated public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
- field public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
- field public static final String ACTION_RESTRICT_BACKGROUND_CHANGED = "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
- field @Deprecated public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
- field @Deprecated public static final int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
- field public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
- field public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
- field @Deprecated public static final String EXTRA_EXTRA_INFO = "extraInfo";
- field @Deprecated public static final String EXTRA_IS_FAILOVER = "isFailover";
- field public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
- field @Deprecated public static final String EXTRA_NETWORK_INFO = "networkInfo";
- field public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
- field @Deprecated public static final String EXTRA_NETWORK_TYPE = "networkType";
- field public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
- field @Deprecated public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
- field public static final String EXTRA_REASON = "reason";
- field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
- field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
- field public static final int MULTIPATH_PREFERENCE_RELIABILITY = 2; // 0x2
- field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
- field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
- field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
- field @Deprecated public static final int TYPE_BLUETOOTH = 7; // 0x7
- field @Deprecated public static final int TYPE_DUMMY = 8; // 0x8
- field @Deprecated public static final int TYPE_ETHERNET = 9; // 0x9
- field @Deprecated public static final int TYPE_MOBILE = 0; // 0x0
- field @Deprecated public static final int TYPE_MOBILE_DUN = 4; // 0x4
- field @Deprecated public static final int TYPE_MOBILE_HIPRI = 5; // 0x5
- field @Deprecated public static final int TYPE_MOBILE_MMS = 2; // 0x2
- field @Deprecated public static final int TYPE_MOBILE_SUPL = 3; // 0x3
- field @Deprecated public static final int TYPE_VPN = 17; // 0x11
- field @Deprecated public static final int TYPE_WIFI = 1; // 0x1
- field @Deprecated public static final int TYPE_WIMAX = 6; // 0x6
- }
-
- public static class ConnectivityManager.NetworkCallback {
- ctor public ConnectivityManager.NetworkCallback();
- ctor public ConnectivityManager.NetworkCallback(int);
- method public void onAvailable(@NonNull android.net.Network);
- method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
- method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
- method public void onLinkPropertiesChanged(@NonNull android.net.Network, @NonNull android.net.LinkProperties);
- method public void onLosing(@NonNull android.net.Network, int);
- method public void onLost(@NonNull android.net.Network);
- method public void onUnavailable();
- field public static final int FLAG_INCLUDE_LOCATION_INFO = 1; // 0x1
- }
-
- public static interface ConnectivityManager.OnNetworkActiveListener {
- method public void onNetworkActive();
- }
-
- public class DhcpInfo implements android.os.Parcelable {
- ctor public DhcpInfo();
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpInfo> CREATOR;
- field public int dns1;
- field public int dns2;
- field public int gateway;
- field public int ipAddress;
- field public int leaseDuration;
- field public int netmask;
- field public int serverAddress;
- }
-
- public final class DnsResolver {
- method @NonNull public static android.net.DnsResolver getInstance();
- method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
- method public void query(@Nullable android.net.Network, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
- method public void rawQuery(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
- method public void rawQuery(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
- field public static final int CLASS_IN = 1; // 0x1
- field public static final int ERROR_PARSE = 0; // 0x0
- field public static final int ERROR_SYSTEM = 1; // 0x1
- field public static final int FLAG_EMPTY = 0; // 0x0
- field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
- field public static final int FLAG_NO_CACHE_STORE = 2; // 0x2
- field public static final int FLAG_NO_RETRY = 1; // 0x1
- field public static final int TYPE_A = 1; // 0x1
- field public static final int TYPE_AAAA = 28; // 0x1c
- }
-
- public static interface DnsResolver.Callback<T> {
- method public void onAnswer(@NonNull T, int);
- method public void onError(@NonNull android.net.DnsResolver.DnsException);
- }
-
- public static class DnsResolver.DnsException extends java.lang.Exception {
- ctor public DnsResolver.DnsException(int, @Nullable Throwable);
- field public final int code;
- }
-
- public class InetAddresses {
- method public static boolean isNumericAddress(@NonNull String);
- method @NonNull public static java.net.InetAddress parseNumericAddress(@NonNull String);
- }
-
- public final class IpConfiguration implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public android.net.ProxyInfo getHttpProxy();
- method @Nullable public android.net.StaticIpConfiguration getStaticIpConfiguration();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.IpConfiguration> CREATOR;
- }
-
- public static final class IpConfiguration.Builder {
- ctor public IpConfiguration.Builder();
- method @NonNull public android.net.IpConfiguration build();
- method @NonNull public android.net.IpConfiguration.Builder setHttpProxy(@Nullable android.net.ProxyInfo);
- method @NonNull public android.net.IpConfiguration.Builder setStaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
- }
-
- public final class IpPrefix implements android.os.Parcelable {
- ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
- method public boolean contains(@NonNull java.net.InetAddress);
- method public int describeContents();
- method @NonNull public java.net.InetAddress getAddress();
- method @IntRange(from=0, to=128) public int getPrefixLength();
- method @NonNull public byte[] getRawAddress();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
- }
-
- public class LinkAddress implements android.os.Parcelable {
- method public int describeContents();
- method public java.net.InetAddress getAddress();
- method public int getFlags();
- method @IntRange(from=0, to=128) public int getPrefixLength();
- method public int getScope();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkAddress> CREATOR;
- }
-
- public final class LinkProperties implements android.os.Parcelable {
- ctor public LinkProperties();
- method public boolean addRoute(@NonNull android.net.RouteInfo);
- method public void clear();
- method public int describeContents();
- method @Nullable public java.net.Inet4Address getDhcpServerAddress();
- method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
- method @Nullable public String getDomains();
- method @Nullable public android.net.ProxyInfo getHttpProxy();
- method @Nullable public String getInterfaceName();
- method @NonNull public java.util.List<android.net.LinkAddress> getLinkAddresses();
- method public int getMtu();
- method @Nullable public android.net.IpPrefix getNat64Prefix();
- method @Nullable public String getPrivateDnsServerName();
- method @NonNull public java.util.List<android.net.RouteInfo> getRoutes();
- method public boolean isPrivateDnsActive();
- method public boolean isWakeOnLanSupported();
- method public void setDhcpServerAddress(@Nullable java.net.Inet4Address);
- method public void setDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
- method public void setDomains(@Nullable String);
- method public void setHttpProxy(@Nullable android.net.ProxyInfo);
- method public void setInterfaceName(@Nullable String);
- method public void setLinkAddresses(@NonNull java.util.Collection<android.net.LinkAddress>);
- method public void setMtu(int);
- method public void setNat64Prefix(@Nullable android.net.IpPrefix);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkProperties> CREATOR;
- }
-
- public final class MacAddress implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public static android.net.MacAddress fromBytes(@NonNull byte[]);
- method @NonNull public static android.net.MacAddress fromString(@NonNull String);
- method public int getAddressType();
- method @Nullable public java.net.Inet6Address getLinkLocalIpv6FromEui48Mac();
- method public boolean isLocallyAssigned();
- method public boolean matches(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
- method @NonNull public byte[] toByteArray();
- method @NonNull public String toOuiString();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.net.MacAddress BROADCAST_ADDRESS;
- field @NonNull public static final android.os.Parcelable.Creator<android.net.MacAddress> CREATOR;
- field public static final int TYPE_BROADCAST = 3; // 0x3
- field public static final int TYPE_MULTICAST = 2; // 0x2
- field public static final int TYPE_UNICAST = 1; // 0x1
- }
-
- public class Network implements android.os.Parcelable {
- method public void bindSocket(java.net.DatagramSocket) throws java.io.IOException;
- method public void bindSocket(java.net.Socket) throws java.io.IOException;
- method public void bindSocket(java.io.FileDescriptor) throws java.io.IOException;
- method public int describeContents();
- method public static android.net.Network fromNetworkHandle(long);
- method public java.net.InetAddress[] getAllByName(String) throws java.net.UnknownHostException;
- method public java.net.InetAddress getByName(String) throws java.net.UnknownHostException;
- method public long getNetworkHandle();
- method public javax.net.SocketFactory getSocketFactory();
- method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
- method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.Network> CREATOR;
- }
-
- public final class NetworkCapabilities implements android.os.Parcelable {
- ctor public NetworkCapabilities();
- ctor public NetworkCapabilities(android.net.NetworkCapabilities);
- method public int describeContents();
- method @NonNull public int[] getCapabilities();
- method @NonNull public int[] getEnterpriseIds();
- method public int getLinkDownstreamBandwidthKbps();
- method public int getLinkUpstreamBandwidthKbps();
- method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
- method public int getOwnerUid();
- method public int getSignalStrength();
- method @Nullable public android.net.TransportInfo getTransportInfo();
- method public boolean hasCapability(int);
- method public boolean hasEnterpriseId(int);
- method public boolean hasTransport(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
- field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
- field public static final int NET_CAPABILITY_CBS = 5; // 0x5
- field public static final int NET_CAPABILITY_DUN = 2; // 0x2
- field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
- field public static final int NET_CAPABILITY_ENTERPRISE = 29; // 0x1d
- field public static final int NET_CAPABILITY_FOREGROUND = 19; // 0x13
- field public static final int NET_CAPABILITY_FOTA = 3; // 0x3
- field public static final int NET_CAPABILITY_HEAD_UNIT = 32; // 0x20
- field public static final int NET_CAPABILITY_IA = 7; // 0x7
- field public static final int NET_CAPABILITY_IMS = 4; // 0x4
- field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
- field public static final int NET_CAPABILITY_MCX = 23; // 0x17
- field public static final int NET_CAPABILITY_MMS = 0; // 0x0
- field public static final int NET_CAPABILITY_MMTEL = 33; // 0x21
- field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14
- field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
- field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
- field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
- field public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; // 0x15
- field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
- field public static final int NET_CAPABILITY_PRIORITIZE_BANDWIDTH = 35; // 0x23
- field public static final int NET_CAPABILITY_PRIORITIZE_LATENCY = 34; // 0x22
- field public static final int NET_CAPABILITY_RCS = 8; // 0x8
- field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
- field public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; // 0x19
- field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
- field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
- field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
- field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
- field public static final int NET_ENTERPRISE_ID_1 = 1; // 0x1
- field public static final int NET_ENTERPRISE_ID_2 = 2; // 0x2
- field public static final int NET_ENTERPRISE_ID_3 = 3; // 0x3
- field public static final int NET_ENTERPRISE_ID_4 = 4; // 0x4
- field public static final int NET_ENTERPRISE_ID_5 = 5; // 0x5
- field public static final int SIGNAL_STRENGTH_UNSPECIFIED = -2147483648; // 0x80000000
- field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
- field public static final int TRANSPORT_CELLULAR = 0; // 0x0
- field public static final int TRANSPORT_ETHERNET = 3; // 0x3
- field public static final int TRANSPORT_LOWPAN = 6; // 0x6
- field public static final int TRANSPORT_THREAD = 9; // 0x9
- field public static final int TRANSPORT_USB = 8; // 0x8
- field public static final int TRANSPORT_VPN = 4; // 0x4
- field public static final int TRANSPORT_WIFI = 1; // 0x1
- field public static final int TRANSPORT_WIFI_AWARE = 5; // 0x5
- }
-
- @Deprecated public class NetworkInfo implements android.os.Parcelable {
- ctor @Deprecated public NetworkInfo(int, int, @Nullable String, @Nullable String);
- method @Deprecated public int describeContents();
- method @Deprecated @NonNull public android.net.NetworkInfo.DetailedState getDetailedState();
- method @Deprecated public String getExtraInfo();
- method @Deprecated public String getReason();
- method @Deprecated public android.net.NetworkInfo.State getState();
- method @Deprecated public int getSubtype();
- method @Deprecated public String getSubtypeName();
- method @Deprecated public int getType();
- method @Deprecated public String getTypeName();
- method @Deprecated public boolean isAvailable();
- method @Deprecated public boolean isConnected();
- method @Deprecated public boolean isConnectedOrConnecting();
- method @Deprecated public boolean isFailover();
- method @Deprecated public boolean isRoaming();
- method @Deprecated public void setDetailedState(@NonNull android.net.NetworkInfo.DetailedState, @Nullable String, @Nullable String);
- method @Deprecated public void writeToParcel(android.os.Parcel, int);
- field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
- }
-
- @Deprecated public enum NetworkInfo.DetailedState {
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState AUTHENTICATING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState BLOCKED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CAPTIVE_PORTAL_CHECK;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState FAILED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState IDLE;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState OBTAINING_IPADDR;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SCANNING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SUSPENDED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState VERIFYING_POOR_LINK;
- }
-
- @Deprecated public enum NetworkInfo.State {
- enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTING;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State SUSPENDED;
- enum_constant @Deprecated public static final android.net.NetworkInfo.State UNKNOWN;
- }
-
- public class NetworkRequest implements android.os.Parcelable {
- method public boolean canBeSatisfiedBy(@Nullable android.net.NetworkCapabilities);
- method public int describeContents();
- method @NonNull public int[] getCapabilities();
- method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
- method @NonNull public int[] getTransportTypes();
- method public boolean hasCapability(int);
- method public boolean hasTransport(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkRequest> CREATOR;
- }
-
- public static class NetworkRequest.Builder {
- ctor public NetworkRequest.Builder();
- ctor public NetworkRequest.Builder(@NonNull android.net.NetworkRequest);
- method public android.net.NetworkRequest.Builder addCapability(int);
- method public android.net.NetworkRequest.Builder addTransportType(int);
- method public android.net.NetworkRequest build();
- method @NonNull public android.net.NetworkRequest.Builder clearCapabilities();
- method public android.net.NetworkRequest.Builder removeCapability(int);
- method public android.net.NetworkRequest.Builder removeTransportType(int);
- method @NonNull public android.net.NetworkRequest.Builder setIncludeOtherUidNetworks(boolean);
- method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
- method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
- }
-
- public class ParseException extends java.lang.RuntimeException {
- ctor public ParseException(@NonNull String);
- ctor public ParseException(@NonNull String, @NonNull Throwable);
- field public String response;
- }
-
- public class ProxyInfo implements android.os.Parcelable {
- ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
- method public static android.net.ProxyInfo buildDirectProxy(String, int);
- method public static android.net.ProxyInfo buildDirectProxy(String, int, java.util.List<java.lang.String>);
- method public static android.net.ProxyInfo buildPacProxy(android.net.Uri);
- method @NonNull public static android.net.ProxyInfo buildPacProxy(@NonNull android.net.Uri, int);
- method public int describeContents();
- method public String[] getExclusionList();
- method public String getHost();
- method public android.net.Uri getPacFileUrl();
- method public int getPort();
- method public boolean isValid();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.ProxyInfo> CREATOR;
- }
-
- public final class RouteInfo implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.IpPrefix getDestination();
- method @Nullable public java.net.InetAddress getGateway();
- method @Nullable public String getInterface();
- method public int getType();
- method public boolean hasGateway();
- method public boolean isDefaultRoute();
- method public boolean matches(java.net.InetAddress);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.RouteInfo> CREATOR;
- field public static final int RTN_THROW = 9; // 0x9
- field public static final int RTN_UNICAST = 1; // 0x1
- field public static final int RTN_UNREACHABLE = 7; // 0x7
- }
-
- public abstract class SocketKeepalive implements java.lang.AutoCloseable {
- method public final void close();
- method public final void start(@IntRange(from=0xa, to=0xe10) int);
- method public final void stop();
- field public static final int ERROR_HARDWARE_ERROR = -31; // 0xffffffe1
- field public static final int ERROR_INSUFFICIENT_RESOURCES = -32; // 0xffffffe0
- field public static final int ERROR_INVALID_INTERVAL = -24; // 0xffffffe8
- field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
- field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
- field public static final int ERROR_INVALID_NETWORK = -20; // 0xffffffec
- field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
- field public static final int ERROR_INVALID_SOCKET = -25; // 0xffffffe7
- field public static final int ERROR_SOCKET_NOT_IDLE = -26; // 0xffffffe6
- field public static final int ERROR_UNSUPPORTED = -30; // 0xffffffe2
- }
-
- public static class SocketKeepalive.Callback {
- ctor public SocketKeepalive.Callback();
- method public void onDataReceived();
- method public void onError(int);
- method public void onStarted();
- method public void onStopped();
- }
-
- public final class StaticIpConfiguration implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
- method @Nullable public String getDomains();
- method @Nullable public java.net.InetAddress getGateway();
- method @NonNull public android.net.LinkAddress getIpAddress();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.StaticIpConfiguration> CREATOR;
- }
-
- public static final class StaticIpConfiguration.Builder {
- ctor public StaticIpConfiguration.Builder();
- method @NonNull public android.net.StaticIpConfiguration build();
- method @NonNull public android.net.StaticIpConfiguration.Builder setDnsServers(@NonNull Iterable<java.net.InetAddress>);
- method @NonNull public android.net.StaticIpConfiguration.Builder setDomains(@Nullable String);
- method @NonNull public android.net.StaticIpConfiguration.Builder setGateway(@Nullable java.net.InetAddress);
- method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@NonNull android.net.LinkAddress);
- }
-
- public interface TransportInfo {
- }
-
-}
-
diff --git a/framework/cronet_disabled/api/lint-baseline.txt b/framework/cronet_disabled/api/lint-baseline.txt
deleted file mode 100644
index 2f4004a..0000000
--- a/framework/cronet_disabled/api/lint-baseline.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-// Baseline format: 1.0
-VisiblySynchronized: android.net.NetworkInfo#toString():
- Internal locks must not be exposed (synchronizing on this or class is still
- externally observable): method android.net.NetworkInfo.toString()
diff --git a/framework/cronet_disabled/api/module-lib-current.txt b/framework/cronet_disabled/api/module-lib-current.txt
deleted file mode 100644
index 193bd92..0000000
--- a/framework/cronet_disabled/api/module-lib-current.txt
+++ /dev/null
@@ -1,239 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public final class ConnectivityFrameworkInitializer {
- method public static void registerServiceWrappers();
- }
-
- public class ConnectivityManager {
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void addUidToMeteredNetworkAllowList(int);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void addUidToMeteredNetworkDenyList(int);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void factoryReset();
- method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshots();
- method @Nullable public android.net.ProxyInfo getGlobalProxy();
- method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
- method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.LinkProperties getRedactedLinkPropertiesForPackage(@NonNull android.net.LinkProperties, int, @NonNull String);
- method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.NetworkCapabilities getRedactedNetworkCapabilitiesForPackage(@NonNull android.net.NetworkCapabilities, int, @NonNull String);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkAllowList(int);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkDenyList(int);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void replaceFirewallChain(int, @NonNull int[]);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @Deprecated public boolean requestRouteToHostAddress(int, java.net.InetAddress);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptPartialConnectivity(@NonNull android.net.Network, boolean, boolean);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAcceptUnvalidated(@NonNull android.net.Network, boolean, boolean);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setAvoidUnvalidated(@NonNull android.net.Network);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setFirewallChainEnabled(int, boolean);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setGlobalProxy(@Nullable android.net.ProxyInfo);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setLegacyLockdownVpnEnabled(boolean);
- method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreferences(@NonNull android.os.UserHandle, @NonNull java.util.List<android.net.ProfileNetworkPreference>, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setUidFirewallRule(int, int, int);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setVpnDefaultForUids(@NonNull String, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
- method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
- method public void systemReady();
- field public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE";
- field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION";
- field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY";
- field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
- field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
- field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
- field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000
- field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
- field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
- field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
- field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
- field public static final int BLOCKED_REASON_LOCKDOWN_VPN = 16; // 0x10
- field public static final int BLOCKED_REASON_LOW_POWER_STANDBY = 32; // 0x20
- field public static final int BLOCKED_REASON_NONE = 0; // 0x0
- field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
- field public static final int FIREWALL_CHAIN_DOZABLE = 1; // 0x1
- field public static final int FIREWALL_CHAIN_LOW_POWER_STANDBY = 5; // 0x5
- field public static final int FIREWALL_CHAIN_OEM_DENY_1 = 7; // 0x7
- field public static final int FIREWALL_CHAIN_OEM_DENY_2 = 8; // 0x8
- field public static final int FIREWALL_CHAIN_OEM_DENY_3 = 9; // 0x9
- field public static final int FIREWALL_CHAIN_POWERSAVE = 3; // 0x3
- field public static final int FIREWALL_CHAIN_RESTRICTED = 4; // 0x4
- field public static final int FIREWALL_CHAIN_STANDBY = 2; // 0x2
- field public static final int FIREWALL_RULE_ALLOW = 1; // 0x1
- field public static final int FIREWALL_RULE_DEFAULT = 0; // 0x0
- field public static final int FIREWALL_RULE_DENY = 2; // 0x2
- field public static final int PROFILE_NETWORK_PREFERENCE_DEFAULT = 0; // 0x0
- field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
- field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING = 3; // 0x3
- field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK = 2; // 0x2
- }
-
- public static class ConnectivityManager.NetworkCallback {
- method public void onBlockedStatusChanged(@NonNull android.net.Network, int);
- }
-
- public class ConnectivitySettingsManager {
- method public static void clearGlobalProxy(@NonNull android.content.Context);
- method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context);
- method public static int getCaptivePortalMode(@NonNull android.content.Context, int);
- method @NonNull public static java.time.Duration getConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method @NonNull public static android.util.Range<java.lang.Integer> getDnsResolverSampleRanges(@NonNull android.content.Context);
- method @NonNull public static java.time.Duration getDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static int getDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, int);
- method @Nullable public static android.net.ProxyInfo getGlobalProxy(@NonNull android.content.Context);
- method public static long getIngressRateLimitInBytesPerSecond(@NonNull android.content.Context);
- method @NonNull public static java.time.Duration getMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static boolean getMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
- method @NonNull public static java.util.Set<java.lang.Integer> getMobileDataPreferredUids(@NonNull android.content.Context);
- method public static int getNetworkAvoidBadWifi(@NonNull android.content.Context);
- method @Nullable public static String getNetworkMeteredMultipathPreference(@NonNull android.content.Context);
- method public static int getNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, int);
- method @NonNull public static java.time.Duration getNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method @NonNull public static String getPrivateDnsDefaultMode(@NonNull android.content.Context);
- method @Nullable public static String getPrivateDnsHostname(@NonNull android.content.Context);
- method public static int getPrivateDnsMode(@NonNull android.content.Context);
- method @NonNull public static java.util.Set<java.lang.Integer> getUidsAllowedOnRestrictedNetworks(@NonNull android.content.Context);
- method public static boolean getWifiAlwaysRequested(@NonNull android.content.Context, boolean);
- method @NonNull public static java.time.Duration getWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setCaptivePortalHttpUrl(@NonNull android.content.Context, @Nullable String);
- method public static void setCaptivePortalMode(@NonNull android.content.Context, int);
- method public static void setConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setDnsResolverSampleRanges(@NonNull android.content.Context, @NonNull android.util.Range<java.lang.Integer>);
- method public static void setDnsResolverSampleValidityDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setDnsResolverSuccessThresholdPercent(@NonNull android.content.Context, @IntRange(from=0, to=100) int);
- method public static void setGlobalProxy(@NonNull android.content.Context, @NonNull android.net.ProxyInfo);
- method public static void setIngressRateLimitInBytesPerSecond(@NonNull android.content.Context, @IntRange(from=-1L, to=4294967295L) long);
- method public static void setMobileDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setMobileDataAlwaysOn(@NonNull android.content.Context, boolean);
- method public static void setMobileDataPreferredUids(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
- method public static void setNetworkAvoidBadWifi(@NonNull android.content.Context, int);
- method public static void setNetworkMeteredMultipathPreference(@NonNull android.content.Context, @NonNull String);
- method public static void setNetworkSwitchNotificationMaximumDailyCount(@NonNull android.content.Context, @IntRange(from=0) int);
- method public static void setNetworkSwitchNotificationRateDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
- method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull int);
- method public static void setPrivateDnsHostname(@NonNull android.content.Context, @Nullable String);
- method public static void setPrivateDnsMode(@NonNull android.content.Context, int);
- method public static void setUidsAllowedOnRestrictedNetworks(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
- method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean);
- method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
- field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2
- field public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0; // 0x0
- field public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1; // 0x1
- field public static final int NETWORK_AVOID_BAD_WIFI_AVOID = 2; // 0x2
- field public static final int NETWORK_AVOID_BAD_WIFI_IGNORE = 0; // 0x0
- field public static final int NETWORK_AVOID_BAD_WIFI_PROMPT = 1; // 0x1
- field public static final int PRIVATE_DNS_MODE_OFF = 1; // 0x1
- field public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2; // 0x2
- field public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3; // 0x3
- }
-
- public final class DhcpOption implements android.os.Parcelable {
- ctor public DhcpOption(byte, @Nullable byte[]);
- method public int describeContents();
- method public byte getType();
- method @Nullable public byte[] getValue();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpOption> CREATOR;
- }
-
- public final class NetworkAgentConfig implements android.os.Parcelable {
- method @Nullable public String getSubscriberId();
- method public boolean isBypassableVpn();
- method public boolean isVpnValidationRequired();
- }
-
- public static final class NetworkAgentConfig.Builder {
- method @NonNull public android.net.NetworkAgentConfig.Builder setBypassableVpn(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLocalRoutesExcludedForVpn(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
- method @NonNull public android.net.NetworkAgentConfig.Builder setVpnRequiresValidation(boolean);
- }
-
- public final class NetworkCapabilities implements android.os.Parcelable {
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public java.util.Set<java.lang.Integer> getAllowedUids();
- method @Nullable public java.util.Set<android.util.Range<java.lang.Integer>> getUids();
- method public boolean hasForbiddenCapability(int);
- field public static final long REDACT_ALL = -1L; // 0xffffffffffffffffL
- field public static final long REDACT_FOR_ACCESS_FINE_LOCATION = 1L; // 0x1L
- field public static final long REDACT_FOR_LOCAL_MAC_ADDRESS = 2L; // 0x2L
- field public static final long REDACT_FOR_NETWORK_SETTINGS = 4L; // 0x4L
- field public static final long REDACT_NONE = 0L; // 0x0L
- field public static final int TRANSPORT_TEST = 7; // 0x7
- }
-
- public static final class NetworkCapabilities.Builder {
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAllowedUids(@NonNull java.util.Set<java.lang.Integer>);
- method @NonNull public android.net.NetworkCapabilities.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
- }
-
- public class NetworkRequest implements android.os.Parcelable {
- method @NonNull public int[] getEnterpriseIds();
- method @NonNull public int[] getForbiddenCapabilities();
- method public boolean hasEnterpriseId(int);
- method public boolean hasForbiddenCapability(int);
- }
-
- public static class NetworkRequest.Builder {
- method @NonNull public android.net.NetworkRequest.Builder addForbiddenCapability(int);
- method @NonNull public android.net.NetworkRequest.Builder removeForbiddenCapability(int);
- method @NonNull public android.net.NetworkRequest.Builder setUids(@Nullable java.util.Set<android.util.Range<java.lang.Integer>>);
- }
-
- public final class ProfileNetworkPreference implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public int[] getExcludedUids();
- method @NonNull public int[] getIncludedUids();
- method public int getPreference();
- method public int getPreferenceEnterpriseId();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.ProfileNetworkPreference> CREATOR;
- }
-
- public static final class ProfileNetworkPreference.Builder {
- ctor public ProfileNetworkPreference.Builder();
- method @NonNull public android.net.ProfileNetworkPreference build();
- method @NonNull public android.net.ProfileNetworkPreference.Builder setExcludedUids(@NonNull int[]);
- method @NonNull public android.net.ProfileNetworkPreference.Builder setIncludedUids(@NonNull int[]);
- method @NonNull public android.net.ProfileNetworkPreference.Builder setPreference(int);
- method @NonNull public android.net.ProfileNetworkPreference.Builder setPreferenceEnterpriseId(int);
- }
-
- public final class TestNetworkInterface implements android.os.Parcelable {
- ctor public TestNetworkInterface(@NonNull android.os.ParcelFileDescriptor, @NonNull String);
- method public int describeContents();
- method @NonNull public android.os.ParcelFileDescriptor getFileDescriptor();
- method @NonNull public String getInterfaceName();
- method @Nullable public android.net.MacAddress getMacAddress();
- method public int getMtu();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkInterface> CREATOR;
- }
-
- public class TestNetworkManager {
- method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public android.net.TestNetworkInterface createTapInterface();
- method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public android.net.TestNetworkInterface createTunInterface(@NonNull java.util.Collection<android.net.LinkAddress>);
- method @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder);
- method @RequiresPermission(android.Manifest.permission.MANAGE_TEST_NETWORKS) public void teardownTestNetwork(@NonNull android.net.Network);
- field public static final String TEST_TAP_PREFIX = "testtap";
- }
-
- public final class TestNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
- ctor public TestNetworkSpecifier(@NonNull String);
- method public int describeContents();
- method @Nullable public String getInterfaceName();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkSpecifier> CREATOR;
- }
-
- public interface TransportInfo {
- method public default long getApplicableRedactions();
- method @NonNull public default android.net.TransportInfo makeCopy(long);
- }
-
- public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
- ctor @Deprecated public VpnTransportInfo(int, @Nullable String);
- method @Nullable public String getSessionId();
- method @NonNull public android.net.VpnTransportInfo makeCopy(long);
- }
-
-}
-
diff --git a/framework/cronet_disabled/api/module-lib-removed.txt b/framework/cronet_disabled/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/framework/cronet_disabled/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/framework/cronet_disabled/api/removed.txt b/framework/cronet_disabled/api/removed.txt
deleted file mode 100644
index 303a1e6..0000000
--- a/framework/cronet_disabled/api/removed.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public class ConnectivityManager {
- method @Deprecated public boolean requestRouteToHost(int, int);
- method @Deprecated public int startUsingNetworkFeature(int, String);
- method @Deprecated public int stopUsingNetworkFeature(int, String);
- }
-
-}
-
diff --git a/framework/cronet_disabled/api/system-current.txt b/framework/cronet_disabled/api/system-current.txt
deleted file mode 100644
index 4a2ed8a..0000000
--- a/framework/cronet_disabled/api/system-current.txt
+++ /dev/null
@@ -1,544 +0,0 @@
-// Signature format: 2.0
-package android.net {
-
- public class CaptivePortal implements android.os.Parcelable {
- method @Deprecated public void logEvent(int, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void reevaluateNetwork();
- method public void useNetwork();
- field public static final int APP_REQUEST_REEVALUATION_REQUIRED = 100; // 0x64
- field public static final int APP_RETURN_DISMISSED = 0; // 0x0
- field public static final int APP_RETURN_UNWANTED = 1; // 0x1
- field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
- }
-
- public final class CaptivePortalData implements android.os.Parcelable {
- method public int describeContents();
- method public long getByteLimit();
- method public long getExpiryTimeMillis();
- method public long getRefreshTimeMillis();
- method @Nullable public android.net.Uri getUserPortalUrl();
- method public int getUserPortalUrlSource();
- method @Nullable public CharSequence getVenueFriendlyName();
- method @Nullable public android.net.Uri getVenueInfoUrl();
- method public int getVenueInfoUrlSource();
- method public boolean isCaptive();
- method public boolean isSessionExtendable();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final int CAPTIVE_PORTAL_DATA_SOURCE_OTHER = 0; // 0x0
- field public static final int CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT = 1; // 0x1
- field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortalData> CREATOR;
- }
-
- public static class CaptivePortalData.Builder {
- ctor public CaptivePortalData.Builder();
- ctor public CaptivePortalData.Builder(@Nullable android.net.CaptivePortalData);
- method @NonNull public android.net.CaptivePortalData build();
- method @NonNull public android.net.CaptivePortalData.Builder setBytesRemaining(long);
- method @NonNull public android.net.CaptivePortalData.Builder setCaptive(boolean);
- method @NonNull public android.net.CaptivePortalData.Builder setExpiryTime(long);
- method @NonNull public android.net.CaptivePortalData.Builder setRefreshTime(long);
- method @NonNull public android.net.CaptivePortalData.Builder setSessionExtendable(boolean);
- method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri);
- method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri, int);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueFriendlyName(@Nullable CharSequence);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri);
- method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri, int);
- }
-
- public class ConnectivityManager {
- method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCaptivePortalServerUrl();
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
- method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull java.util.concurrent.Executor, @NonNull android.net.QosCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
- method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
- method @RequiresPermission(android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE) public void setOemNetworkPreference(@NonNull android.net.OemNetworkPreferences, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
- method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
- method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider);
- method public void unregisterQosCallback(@NonNull android.net.QosCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
- field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
- field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
- field public static final int TETHERING_BLUETOOTH = 2; // 0x2
- field public static final int TETHERING_USB = 1; // 0x1
- field public static final int TETHERING_WIFI = 0; // 0x0
- field @Deprecated public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13; // 0xd
- field @Deprecated public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
- field @Deprecated public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
- field public static final int TYPE_NONE = -1; // 0xffffffff
- field @Deprecated public static final int TYPE_PROXY = 16; // 0x10
- field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd
- }
-
- @Deprecated public abstract static class ConnectivityManager.OnStartTetheringCallback {
- ctor @Deprecated public ConnectivityManager.OnStartTetheringCallback();
- method @Deprecated public void onTetheringFailed();
- method @Deprecated public void onTetheringStarted();
- }
-
- @Deprecated public static interface ConnectivityManager.OnTetheringEntitlementResultListener {
- method @Deprecated public void onTetheringEntitlementResult(int);
- }
-
- @Deprecated public abstract static class ConnectivityManager.OnTetheringEventCallback {
- ctor @Deprecated public ConnectivityManager.OnTetheringEventCallback();
- method @Deprecated public void onUpstreamChanged(@Nullable android.net.Network);
- }
-
- public final class DscpPolicy implements android.os.Parcelable {
- method @Nullable public java.net.InetAddress getDestinationAddress();
- method @Nullable public android.util.Range<java.lang.Integer> getDestinationPortRange();
- method public int getDscpValue();
- method public int getPolicyId();
- method public int getProtocol();
- method @Nullable public java.net.InetAddress getSourceAddress();
- method public int getSourcePort();
- field @NonNull public static final android.os.Parcelable.Creator<android.net.DscpPolicy> CREATOR;
- field public static final int PROTOCOL_ANY = -1; // 0xffffffff
- field public static final int SOURCE_PORT_ANY = -1; // 0xffffffff
- }
-
- public static final class DscpPolicy.Builder {
- ctor public DscpPolicy.Builder(int, int);
- method @NonNull public android.net.DscpPolicy build();
- method @NonNull public android.net.DscpPolicy.Builder setDestinationAddress(@NonNull java.net.InetAddress);
- method @NonNull public android.net.DscpPolicy.Builder setDestinationPortRange(@NonNull android.util.Range<java.lang.Integer>);
- method @NonNull public android.net.DscpPolicy.Builder setProtocol(int);
- method @NonNull public android.net.DscpPolicy.Builder setSourceAddress(@NonNull java.net.InetAddress);
- method @NonNull public android.net.DscpPolicy.Builder setSourcePort(int);
- }
-
- public final class InvalidPacketException extends java.lang.Exception {
- ctor public InvalidPacketException(int);
- method public int getError();
- field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
- field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
- field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
- }
-
- public final class IpConfiguration implements android.os.Parcelable {
- ctor public IpConfiguration();
- ctor public IpConfiguration(@NonNull android.net.IpConfiguration);
- method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment();
- method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
- method public void setHttpProxy(@Nullable android.net.ProxyInfo);
- method public void setIpAssignment(@NonNull android.net.IpConfiguration.IpAssignment);
- method public void setProxySettings(@NonNull android.net.IpConfiguration.ProxySettings);
- method public void setStaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
- }
-
- public enum IpConfiguration.IpAssignment {
- enum_constant public static final android.net.IpConfiguration.IpAssignment DHCP;
- enum_constant public static final android.net.IpConfiguration.IpAssignment STATIC;
- enum_constant public static final android.net.IpConfiguration.IpAssignment UNASSIGNED;
- }
-
- public enum IpConfiguration.ProxySettings {
- enum_constant public static final android.net.IpConfiguration.ProxySettings NONE;
- enum_constant public static final android.net.IpConfiguration.ProxySettings PAC;
- enum_constant public static final android.net.IpConfiguration.ProxySettings STATIC;
- enum_constant public static final android.net.IpConfiguration.ProxySettings UNASSIGNED;
- }
-
- public final class IpPrefix implements android.os.Parcelable {
- ctor public IpPrefix(@NonNull String);
- }
-
- public class KeepalivePacketData {
- ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull byte[]) throws android.net.InvalidPacketException;
- method @NonNull public java.net.InetAddress getDstAddress();
- method public int getDstPort();
- method @NonNull public byte[] getPacket();
- method @NonNull public java.net.InetAddress getSrcAddress();
- method public int getSrcPort();
- }
-
- public class LinkAddress implements android.os.Parcelable {
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int, long, long);
- ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
- ctor public LinkAddress(@NonNull String);
- ctor public LinkAddress(@NonNull String, int, int);
- method public long getDeprecationTime();
- method public long getExpirationTime();
- method public boolean isGlobalPreferred();
- method public boolean isIpv4();
- method public boolean isIpv6();
- method public boolean isSameAddressAs(@Nullable android.net.LinkAddress);
- field public static final long LIFETIME_PERMANENT = 9223372036854775807L; // 0x7fffffffffffffffL
- field public static final long LIFETIME_UNKNOWN = -1L; // 0xffffffffffffffffL
- }
-
- public final class LinkProperties implements android.os.Parcelable {
- ctor public LinkProperties(@Nullable android.net.LinkProperties);
- ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean);
- method public boolean addDnsServer(@NonNull java.net.InetAddress);
- method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
- method public boolean addPcscfServer(@NonNull java.net.InetAddress);
- method @NonNull public java.util.List<java.net.InetAddress> getAddresses();
- method @NonNull public java.util.List<java.lang.String> getAllInterfaceNames();
- method @NonNull public java.util.List<android.net.LinkAddress> getAllLinkAddresses();
- method @NonNull public java.util.List<android.net.RouteInfo> getAllRoutes();
- method @Nullable public android.net.Uri getCaptivePortalApiUrl();
- method @Nullable public android.net.CaptivePortalData getCaptivePortalData();
- method @NonNull public java.util.List<java.net.InetAddress> getPcscfServers();
- method @Nullable public String getTcpBufferSizes();
- method @NonNull public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
- method public boolean hasGlobalIpv6Address();
- method public boolean hasIpv4Address();
- method public boolean hasIpv4DefaultRoute();
- method public boolean hasIpv4DnsServer();
- method public boolean hasIpv6DefaultRoute();
- method public boolean hasIpv6DnsServer();
- method public boolean isIpv4Provisioned();
- method public boolean isIpv6Provisioned();
- method public boolean isProvisioned();
- method public boolean isReachable(@NonNull java.net.InetAddress);
- method public boolean removeDnsServer(@NonNull java.net.InetAddress);
- method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
- method public boolean removeRoute(@NonNull android.net.RouteInfo);
- method public void setCaptivePortalApiUrl(@Nullable android.net.Uri);
- method public void setCaptivePortalData(@Nullable android.net.CaptivePortalData);
- method public void setPcscfServers(@NonNull java.util.Collection<java.net.InetAddress>);
- method public void setPrivateDnsServerName(@Nullable String);
- method public void setTcpBufferSizes(@Nullable String);
- method public void setUsePrivateDns(boolean);
- method public void setValidatedPrivateDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
- }
-
- public final class NattKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
- ctor public NattKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException;
- method public int describeContents();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NattKeepalivePacketData> CREATOR;
- }
-
- public class Network implements android.os.Parcelable {
- ctor public Network(@NonNull android.net.Network);
- method public int getNetId();
- method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
- }
-
- public abstract class NetworkAgent {
- ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
- ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkScore, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
- method @Nullable public android.net.Network getNetwork();
- method public void markConnected();
- method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
- method public void onAutomaticReconnectDisabled();
- method public void onBandwidthUpdateRequested();
- method public void onDscpPolicyStatusUpdated(int, int);
- method public void onNetworkCreated();
- method public void onNetworkDestroyed();
- method public void onNetworkUnwanted();
- method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
- method public void onQosCallbackUnregistered(int);
- method public void onRemoveKeepalivePacketFilter(int);
- method public void onSaveAcceptUnvalidated(boolean);
- method public void onSignalStrengthThresholdsUpdated(@NonNull int[]);
- method public void onStartSocketKeepalive(int, @NonNull java.time.Duration, @NonNull android.net.KeepalivePacketData);
- method public void onStopSocketKeepalive(int);
- method public void onValidationStatus(int, @Nullable android.net.Uri);
- method @NonNull public android.net.Network register();
- method public void sendAddDscpPolicy(@NonNull android.net.DscpPolicy);
- method public void sendLinkProperties(@NonNull android.net.LinkProperties);
- method public void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
- method public void sendNetworkScore(@NonNull android.net.NetworkScore);
- method public void sendNetworkScore(@IntRange(from=0, to=99) int);
- method public final void sendQosCallbackError(int, int);
- method public final void sendQosSessionAvailable(int, int, @NonNull android.net.QosSessionAttributes);
- method public final void sendQosSessionLost(int, int, int);
- method public void sendRemoveAllDscpPolicies();
- method public void sendRemoveDscpPolicy(int);
- method public final void sendSocketKeepaliveEvent(int, int);
- method @Deprecated public void setLegacySubtype(int, @NonNull String);
- method public void setLingerDuration(@NonNull java.time.Duration);
- method public void setTeardownDelayMillis(@IntRange(from=0, to=0x1388) int);
- method public void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
- method public void unregister();
- method public void unregisterAfterReplacement(@IntRange(from=0, to=0x1388) int);
- field public static final int DSCP_POLICY_STATUS_DELETED = 4; // 0x4
- field public static final int DSCP_POLICY_STATUS_INSUFFICIENT_PROCESSING_RESOURCES = 3; // 0x3
- field public static final int DSCP_POLICY_STATUS_POLICY_NOT_FOUND = 5; // 0x5
- field public static final int DSCP_POLICY_STATUS_REQUESTED_CLASSIFIER_NOT_SUPPORTED = 2; // 0x2
- field public static final int DSCP_POLICY_STATUS_REQUEST_DECLINED = 1; // 0x1
- field public static final int DSCP_POLICY_STATUS_SUCCESS = 0; // 0x0
- field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
- field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
- }
-
- public final class NetworkAgentConfig implements android.os.Parcelable {
- method public int describeContents();
- method public int getLegacyType();
- method @NonNull public String getLegacyTypeName();
- method public boolean isExplicitlySelected();
- method public boolean isPartialConnectivityAcceptable();
- method public boolean isUnvalidatedConnectivityAcceptable();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
- }
-
- public static final class NetworkAgentConfig.Builder {
- ctor public NetworkAgentConfig.Builder();
- method @NonNull public android.net.NetworkAgentConfig build();
- method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyExtraInfo(@NonNull String);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubType(int);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacySubTypeName(@NonNull String);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
- method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
- method @NonNull public android.net.NetworkAgentConfig.Builder setNat64DetectionEnabled(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setProvisioningNotificationEnabled(boolean);
- method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
- }
-
- public final class NetworkCapabilities implements android.os.Parcelable {
- method @NonNull public int[] getAdministratorUids();
- method @Nullable public static String getCapabilityCarrierName(int);
- method @Nullable public String getSsid();
- method @NonNull public java.util.Set<java.lang.Integer> getSubscriptionIds();
- method @NonNull public int[] getTransportTypes();
- method @Nullable public java.util.List<android.net.Network> getUnderlyingNetworks();
- method public boolean isPrivateDnsBroken();
- method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
- field public static final int NET_CAPABILITY_BIP = 31; // 0x1f
- field public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; // 0x1c
- field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
- field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a
- field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
- field public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27; // 0x1b
- field public static final int NET_CAPABILITY_VSIM = 30; // 0x1e
- }
-
- public static final class NetworkCapabilities.Builder {
- ctor public NetworkCapabilities.Builder();
- ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
- method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
- method @NonNull public android.net.NetworkCapabilities.Builder addEnterpriseId(int);
- method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
- method @NonNull public android.net.NetworkCapabilities build();
- method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
- method @NonNull public android.net.NetworkCapabilities.Builder removeEnterpriseId(int);
- method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
- method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
- method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setOwnerUid(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
- method @NonNull public android.net.NetworkCapabilities.Builder setSubscriptionIds(@NonNull java.util.Set<java.lang.Integer>);
- method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
- method @NonNull public static android.net.NetworkCapabilities.Builder withoutDefaultCapabilities();
- }
-
- public class NetworkProvider {
- ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest);
- method public int getProviderId();
- method public void onNetworkRequestWithdrawn(@NonNull android.net.NetworkRequest);
- method public void onNetworkRequested(@NonNull android.net.NetworkRequest, @IntRange(from=0, to=99) int, int);
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void registerNetworkOffer(@NonNull android.net.NetworkScore, @NonNull android.net.NetworkCapabilities, @NonNull java.util.concurrent.Executor, @NonNull android.net.NetworkProvider.NetworkOfferCallback);
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void unregisterNetworkOffer(@NonNull android.net.NetworkProvider.NetworkOfferCallback);
- field public static final int ID_NONE = -1; // 0xffffffff
- }
-
- public static interface NetworkProvider.NetworkOfferCallback {
- method public void onNetworkNeeded(@NonNull android.net.NetworkRequest);
- method public void onNetworkUnneeded(@NonNull android.net.NetworkRequest);
- }
-
- public class NetworkReleasedException extends java.lang.Exception {
- ctor public NetworkReleasedException();
- }
-
- public class NetworkRequest implements android.os.Parcelable {
- method @Nullable public String getRequestorPackageName();
- method public int getRequestorUid();
- }
-
- public static class NetworkRequest.Builder {
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
- method @NonNull public android.net.NetworkRequest.Builder setSubscriptionIds(@NonNull java.util.Set<java.lang.Integer>);
- }
-
- public final class NetworkScore implements android.os.Parcelable {
- method public int describeContents();
- method public int getKeepConnectedReason();
- method public int getLegacyInt();
- method public boolean isExiting();
- method public boolean isTransportPrimary();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkScore> CREATOR;
- field public static final int KEEP_CONNECTED_FOR_HANDOVER = 1; // 0x1
- field public static final int KEEP_CONNECTED_NONE = 0; // 0x0
- }
-
- public static final class NetworkScore.Builder {
- ctor public NetworkScore.Builder();
- method @NonNull public android.net.NetworkScore build();
- method @NonNull public android.net.NetworkScore.Builder setExiting(boolean);
- method @NonNull public android.net.NetworkScore.Builder setKeepConnectedReason(int);
- method @NonNull public android.net.NetworkScore.Builder setLegacyInt(int);
- method @NonNull public android.net.NetworkScore.Builder setTransportPrimary(boolean);
- }
-
- public final class OemNetworkPreferences implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getNetworkPreferences();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.OemNetworkPreferences> CREATOR;
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID = 1; // 0x1
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK = 2; // 0x2
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY = 3; // 0x3
- field public static final int OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY = 4; // 0x4
- field public static final int OEM_NETWORK_PREFERENCE_UNINITIALIZED = 0; // 0x0
- }
-
- public static final class OemNetworkPreferences.Builder {
- ctor public OemNetworkPreferences.Builder();
- ctor public OemNetworkPreferences.Builder(@NonNull android.net.OemNetworkPreferences);
- method @NonNull public android.net.OemNetworkPreferences.Builder addNetworkPreference(@NonNull String, int);
- method @NonNull public android.net.OemNetworkPreferences build();
- method @NonNull public android.net.OemNetworkPreferences.Builder clearNetworkPreference(@NonNull String);
- }
-
- public abstract class QosCallback {
- ctor public QosCallback();
- method public void onError(@NonNull android.net.QosCallbackException);
- method public void onQosSessionAvailable(@NonNull android.net.QosSession, @NonNull android.net.QosSessionAttributes);
- method public void onQosSessionLost(@NonNull android.net.QosSession);
- }
-
- public static class QosCallback.QosCallbackRegistrationException extends java.lang.RuntimeException {
- }
-
- public final class QosCallbackException extends java.lang.Exception {
- ctor public QosCallbackException(@NonNull String);
- ctor public QosCallbackException(@NonNull Throwable);
- }
-
- public abstract class QosFilter {
- method @NonNull public abstract android.net.Network getNetwork();
- method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
- method public boolean matchesProtocol(int);
- method public abstract boolean matchesRemoteAddress(@NonNull java.net.InetAddress, int, int);
- }
-
- public final class QosSession implements android.os.Parcelable {
- ctor public QosSession(int, int);
- method public int describeContents();
- method public int getSessionId();
- method public int getSessionType();
- method public long getUniqueId();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
- field public static final int TYPE_EPS_BEARER = 1; // 0x1
- field public static final int TYPE_NR_BEARER = 2; // 0x2
- }
-
- public interface QosSessionAttributes {
- }
-
- public final class QosSocketInfo implements android.os.Parcelable {
- ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
- ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.DatagramSocket) throws java.io.IOException;
- method public int describeContents();
- method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
- method @NonNull public android.net.Network getNetwork();
- method @Nullable public java.net.InetSocketAddress getRemoteSocketAddress();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
- }
-
- public final class RouteInfo implements android.os.Parcelable {
- ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
- ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int, int);
- method public int getMtu();
- }
-
- public abstract class SocketKeepalive implements java.lang.AutoCloseable {
- method public final void start(@IntRange(from=0xa, to=0xe10) int, int, @Nullable android.net.Network);
- field public static final int ERROR_NO_SUCH_SLOT = -33; // 0xffffffdf
- field public static final int FLAG_AUTOMATIC_ON_OFF = 1; // 0x1
- field public static final int SUCCESS = 0; // 0x0
- }
-
- public class SocketLocalAddressChangedException extends java.lang.Exception {
- ctor public SocketLocalAddressChangedException();
- }
-
- public class SocketNotBoundException extends java.lang.Exception {
- ctor public SocketNotBoundException();
- }
-
- public class SocketNotConnectedException extends java.lang.Exception {
- ctor public SocketNotConnectedException();
- }
-
- public class SocketRemoteAddressChangedException extends java.lang.Exception {
- ctor public SocketRemoteAddressChangedException();
- }
-
- public final class StaticIpConfiguration implements android.os.Parcelable {
- ctor public StaticIpConfiguration();
- ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
- method public void addDnsServer(@NonNull java.net.InetAddress);
- method public void clear();
- method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
- }
-
- public final class TcpKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
- ctor public TcpKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[], int, int, int, int, int, int) throws android.net.InvalidPacketException;
- method public int describeContents();
- method public int getIpTos();
- method public int getIpTtl();
- method public int getTcpAck();
- method public int getTcpSeq();
- method public int getTcpWindow();
- method public int getTcpWindowScale();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR;
- }
-
- public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
- ctor public VpnTransportInfo(int, @Nullable String, boolean, boolean);
- method public boolean areLongLivedTcpConnectionsExpensive();
- method public int describeContents();
- method public int getType();
- method public boolean isBypassable();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
- }
-
-}
-
-package android.net.apf {
-
- public final class ApfCapabilities implements android.os.Parcelable {
- ctor public ApfCapabilities(int, int, int);
- method public int describeContents();
- method public static boolean getApfDrop8023Frames();
- method @NonNull public static int[] getApfEtherTypeBlackList();
- method public boolean hasDataAccess();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR;
- field public final int apfPacketFormat;
- field public final int apfVersionSupported;
- field public final int maximumApfProgramSize;
- }
-
-}
-
diff --git a/framework/cronet_disabled/api/system-lint-baseline.txt b/framework/cronet_disabled/api/system-lint-baseline.txt
deleted file mode 100644
index 9a97707..0000000
--- a/framework/cronet_disabled/api/system-lint-baseline.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Baseline format: 1.0
diff --git a/framework/cronet_disabled/api/system-removed.txt b/framework/cronet_disabled/api/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/framework/cronet_disabled/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java
index 67dacb8..ba7df7f 100644
--- a/framework/src/android/net/ConnectivitySettingsManager.java
+++ b/framework/src/android/net/ConnectivitySettingsManager.java
@@ -176,7 +176,9 @@
/**
* When detecting a captive portal, immediately disconnect from the
- * network and do not reconnect to that network in the future.
+ * network and do not reconnect to that network in the future; except
+ * on Wear platform companion proxy networks (transport BLUETOOTH)
+ * will stay behind captive portal.
*/
public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp
index fc680d9..a090a54 100644
--- a/netd/BpfHandler.cpp
+++ b/netd/BpfHandler.cpp
@@ -85,8 +85,24 @@
// U bumps the kernel requirement up to 4.14
if (modules::sdklevel::IsAtLeastU() && !bpf::isAtLeastKernelVersion(4, 14, 0)) abort();
- // V bumps the kernel requirement up to 4.19
- if (modules::sdklevel::IsAtLeastV() && !bpf::isAtLeastKernelVersion(4, 19, 0)) abort();
+ if (modules::sdklevel::IsAtLeastV()) {
+ // V bumps the kernel requirement up to 4.19
+ // see also: //system/netd/tests/kernel_test.cpp TestKernel419
+ if (!bpf::isAtLeastKernelVersion(4, 19, 0)) abort();
+
+ // Technically already required by U, but only enforce on V+
+ // see also: //system/netd/tests/kernel_test.cpp TestKernel64Bit
+ if (bpf::isKernel32Bit() && bpf::isAtLeastKernelVersion(5, 16, 0)) abort();
+ }
+
+ // Linux 6.1 is highest version supported by U, starting with V new kernels,
+ // ie. 6.2+ we are dropping various kernel/system userspace 32-on-64 hacks
+ // (for example "ANDROID: xfrm: remove in_compat_syscall() checks").
+ // Note: this check/enforcement only applies to *system* userspace code,
+ // it does not affect unprivileged apps, the 32-on-64 compatibility
+ // problems are AFAIK limited to various CAP_NET_ADMIN protected interfaces.
+ // see also: //system/bpf/bpfloader/BpfLoader.cpp main()
+ if (bpf::isUserspace32bit() && bpf::isAtLeastKernelVersion(6, 2, 0)) abort();
// U mandates this mount point (though it should also be the case on T)
if (modules::sdklevel::IsAtLeastU() && !!strcmp(cg2_path, "/sys/fs/cgroup")) abort();
@@ -214,7 +230,7 @@
// which might toggle the live stats map and clean it.
const auto countUidStatsEntries = [chargeUid, &totalEntryCount, &perUidEntryCount](
const StatsKey& key,
- const BpfMap<StatsKey, StatsValue>&) {
+ const BpfMapRO<StatsKey, StatsValue>&) {
if (key.uid == chargeUid) {
perUidEntryCount++;
}
@@ -232,9 +248,8 @@
return -EINVAL;
}
- BpfMap<StatsKey, StatsValue>& currentMap =
+ BpfMapRO<StatsKey, StatsValue>& currentMap =
(configuration.value() == SELECT_MAP_A) ? mStatsMapA : mStatsMapB;
- // HACK: mStatsMapB becomes RW BpfMap here, but countUidStatsEntries doesn't modify so it works
base::Result<void> res = currentMap.iterate(countUidStatsEntries);
if (!res.ok()) {
ALOGE("Failed to count the stats entry in map: %s",
diff --git a/netd/BpfHandler.h b/netd/BpfHandler.h
index a6da4eb..9e69efc 100644
--- a/netd/BpfHandler.h
+++ b/netd/BpfHandler.h
@@ -59,10 +59,10 @@
bool hasUpdateDeviceStatsPermission(uid_t uid);
BpfMap<uint64_t, UidTagValue> mCookieTagMap;
- BpfMap<StatsKey, StatsValue> mStatsMapA;
+ BpfMapRO<StatsKey, StatsValue> mStatsMapA;
BpfMapRO<StatsKey, StatsValue> mStatsMapB;
BpfMapRO<uint32_t, uint32_t> mConfigurationMap;
- BpfMap<uint32_t, uint8_t> mUidPermissionMap;
+ BpfMapRO<uint32_t, uint8_t> mUidPermissionMap;
// The limit on the number of stats entries a uid can have in the per uid stats map. BpfHandler
// will block that specific uid from tagging new sockets after the limit is reached.
diff --git a/netd/BpfHandlerTest.cpp b/netd/BpfHandlerTest.cpp
index f5c9a68..b38fa16 100644
--- a/netd/BpfHandlerTest.cpp
+++ b/netd/BpfHandlerTest.cpp
@@ -49,7 +49,7 @@
BpfHandler mBh;
BpfMap<uint64_t, UidTagValue> mFakeCookieTagMap;
BpfMap<StatsKey, StatsValue> mFakeStatsMapA;
- BpfMapRO<uint32_t, uint32_t> mFakeConfigurationMap;
+ BpfMap<uint32_t, uint32_t> mFakeConfigurationMap;
BpfMap<uint32_t, uint8_t> mFakeUidPermissionMap;
void SetUp() {
diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
index fed2979..3101397 100644
--- a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
+++ b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
@@ -41,7 +41,7 @@
using base::Result;
int bpfGetUidStatsInternal(uid_t uid, StatsValue* stats,
- const BpfMap<uint32_t, StatsValue>& appUidStatsMap) {
+ const BpfMapRO<uint32_t, StatsValue>& appUidStatsMap) {
auto statsEntry = appUidStatsMap.readValue(uid);
if (!statsEntry.ok()) {
*stats = {};
@@ -57,14 +57,14 @@
}
int bpfGetIfaceStatsInternal(const char* iface, StatsValue* stats,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceNameMap) {
+ const BpfMapRO<uint32_t, StatsValue>& ifaceStatsMap,
+ const BpfMapRO<uint32_t, IfaceValue>& ifaceNameMap) {
*stats = {};
int64_t unknownIfaceBytesTotal = 0;
const auto processIfaceStats =
[iface, stats, &ifaceNameMap, &unknownIfaceBytesTotal](
const uint32_t& key,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap) -> Result<void> {
+ const BpfMapRO<uint32_t, StatsValue>& ifaceStatsMap) -> Result<void> {
char ifname[IFNAMSIZ];
if (getIfaceNameFromMap(ifaceNameMap, ifaceStatsMap, key, ifname, key,
&unknownIfaceBytesTotal)) {
@@ -90,7 +90,7 @@
}
int bpfGetIfIndexStatsInternal(uint32_t ifindex, StatsValue* stats,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap) {
+ const BpfMapRO<uint32_t, StatsValue>& ifaceStatsMap) {
auto statsEntry = ifaceStatsMap.readValue(ifindex);
if (!statsEntry.ok()) {
*stats = {};
@@ -120,13 +120,13 @@
}
int parseBpfNetworkStatsDetailInternal(std::vector<stats_line>& lines,
- const BpfMap<StatsKey, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap) {
+ const BpfMapRO<StatsKey, StatsValue>& statsMap,
+ const BpfMapRO<uint32_t, IfaceValue>& ifaceMap) {
int64_t unknownIfaceBytesTotal = 0;
const auto processDetailUidStats =
[&lines, &unknownIfaceBytesTotal, &ifaceMap](
const StatsKey& key,
- const BpfMap<StatsKey, StatsValue>& statsMap) -> Result<void> {
+ const BpfMapRO<StatsKey, StatsValue>& statsMap) -> Result<void> {
char ifname[IFNAMSIZ];
if (getIfaceNameFromMap(ifaceMap, statsMap, key.ifaceIndex, ifname, key,
&unknownIfaceBytesTotal)) {
@@ -212,12 +212,12 @@
}
int parseBpfNetworkStatsDevInternal(std::vector<stats_line>& lines,
- const BpfMap<uint32_t, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap) {
+ const BpfMapRO<uint32_t, StatsValue>& statsMap,
+ const BpfMapRO<uint32_t, IfaceValue>& ifaceMap) {
int64_t unknownIfaceBytesTotal = 0;
const auto processDetailIfaceStats = [&lines, &unknownIfaceBytesTotal, &ifaceMap, &statsMap](
const uint32_t& key, const StatsValue& value,
- const BpfMap<uint32_t, StatsValue>&) {
+ const BpfMapRO<uint32_t, StatsValue>&) {
char ifname[IFNAMSIZ];
if (getIfaceNameFromMap(ifaceMap, statsMap, key, ifname, key, &unknownIfaceBytesTotal)) {
return Result<void>();
diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
index 76c56eb..bcc4550 100644
--- a/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
+++ b/service-t/native/libs/libnetworkstats/BpfNetworkStatsTest.cpp
@@ -80,19 +80,19 @@
void SetUp() {
ASSERT_EQ(0, setrlimitForTest());
- mFakeCookieTagMap = BpfMap<uint64_t, UidTagValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
+ mFakeCookieTagMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
ASSERT_TRUE(mFakeCookieTagMap.isValid());
- mFakeAppUidStatsMap = BpfMap<uint32_t, StatsValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
+ mFakeAppUidStatsMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
ASSERT_TRUE(mFakeAppUidStatsMap.isValid());
- mFakeStatsMap = BpfMap<StatsKey, StatsValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
+ mFakeStatsMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
ASSERT_TRUE(mFakeStatsMap.isValid());
- mFakeIfaceIndexNameMap = BpfMap<uint32_t, IfaceValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
+ mFakeIfaceIndexNameMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
ASSERT_TRUE(mFakeIfaceIndexNameMap.isValid());
- mFakeIfaceStatsMap = BpfMap<uint32_t, StatsValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
+ mFakeIfaceStatsMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
ASSERT_TRUE(mFakeIfaceStatsMap.isValid());
}
diff --git a/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h b/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
index ea068fc..8058d05 100644
--- a/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
+++ b/service-t/native/libs/libnetworkstats/include/netdbpf/BpfNetworkStats.h
@@ -57,24 +57,25 @@
// For test only
int bpfGetUidStatsInternal(uid_t uid, StatsValue* stats,
- const BpfMap<uint32_t, StatsValue>& appUidStatsMap);
+ const BpfMapRO<uint32_t, StatsValue>& appUidStatsMap);
// For test only
int bpfGetIfaceStatsInternal(const char* iface, StatsValue* stats,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceNameMap);
+ const BpfMapRO<uint32_t, StatsValue>& ifaceStatsMap,
+ const BpfMapRO<uint32_t, IfaceValue>& ifaceNameMap);
// For test only
int bpfGetIfIndexStatsInternal(uint32_t ifindex, StatsValue* stats,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap);
+ const BpfMapRO<uint32_t, StatsValue>& ifaceStatsMap);
// For test only
int parseBpfNetworkStatsDetailInternal(std::vector<stats_line>& lines,
- const BpfMap<StatsKey, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap);
+ const BpfMapRO<StatsKey, StatsValue>& statsMap,
+ const BpfMapRO<uint32_t, IfaceValue>& ifaceMap);
// For test only
int cleanStatsMapInternal(const base::unique_fd& cookieTagMap, const base::unique_fd& tagStatsMap);
// For test only
template <class Key>
-int getIfaceNameFromMap(const BpfMap<uint32_t, IfaceValue>& ifaceMap,
- const BpfMap<Key, StatsValue>& statsMap, uint32_t ifaceIndex, char* ifname,
+int getIfaceNameFromMap(const BpfMapRO<uint32_t, IfaceValue>& ifaceMap,
+ const BpfMapRO<Key, StatsValue>& statsMap,
+ uint32_t ifaceIndex, char* ifname,
const Key& curKey, int64_t* unknownIfaceBytesTotal) {
auto iface = ifaceMap.readValue(ifaceIndex);
if (!iface.ok()) {
@@ -86,7 +87,7 @@
}
template <class Key>
-void maybeLogUnknownIface(int ifaceIndex, const BpfMap<Key, StatsValue>& statsMap,
+void maybeLogUnknownIface(int ifaceIndex, const BpfMapRO<Key, StatsValue>& statsMap,
const Key& curKey, int64_t* unknownIfaceBytesTotal) {
// Have we already logged an error?
if (*unknownIfaceBytesTotal == -1) {
@@ -110,8 +111,8 @@
// For test only
int parseBpfNetworkStatsDevInternal(std::vector<stats_line>& lines,
- const BpfMap<uint32_t, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap);
+ const BpfMapRO<uint32_t, StatsValue>& statsMap,
+ const BpfMapRO<uint32_t, IfaceValue>& ifaceMap);
int bpfGetUidStats(uid_t uid, StatsValue* stats);
int bpfGetIfaceStats(const char* iface, StatsValue* stats);
diff --git a/service-t/src/com/android/server/NetworkStatsServiceInitializer.java b/service-t/src/com/android/server/NetworkStatsServiceInitializer.java
index 82a4fbd..675e5a1 100644
--- a/service-t/src/com/android/server/NetworkStatsServiceInitializer.java
+++ b/service-t/src/com/android/server/NetworkStatsServiceInitializer.java
@@ -22,6 +22,7 @@
import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.DeviceConfigUtils;
import com.android.server.net.NetworkStatsService;
/**
@@ -30,6 +31,8 @@
*/
public final class NetworkStatsServiceInitializer extends SystemService {
private static final String TAG = NetworkStatsServiceInitializer.class.getSimpleName();
+ private static final String ENABLE_NETWORK_TRACING = "enable_network_tracing";
+ private final boolean mNetworkTracingFlagEnabled;
private final NetworkStatsService mStatsService;
public NetworkStatsServiceInitializer(Context context) {
@@ -37,6 +40,8 @@
// Load JNI libraries used by NetworkStatsService and its dependencies
System.loadLibrary("service-connectivity");
mStatsService = maybeCreateNetworkStatsService(context);
+ mNetworkTracingFlagEnabled = DeviceConfigUtils.isTetheringFeatureEnabled(
+ context, ENABLE_NETWORK_TRACING);
}
@Override
@@ -48,11 +53,10 @@
TrafficStats.init(getContext());
}
- // The following code registers the Perfetto Network Trace Handler on non-user builds.
- // The enhanced tracing is intended to be used for debugging and diagnosing issues. This
- // is conditional on the build type rather than `isDebuggable` to match the system_server
- // selinux rules which only allow the Perfetto connection under the same circumstances.
- if (SdkLevel.isAtLeastU() && !Build.TYPE.equals("user")) {
+ // The following code registers the Perfetto Network Trace Handler. The enhanced tracing
+ // is intended to be used for debugging and diagnosing issues. This is enabled by default
+ // on userdebug/eng builds and flag protected in user builds.
+ if (SdkLevel.isAtLeastU() && (mNetworkTracingFlagEnabled || !Build.TYPE.equals("user"))) {
Log.i(TAG, "Initializing network tracing hooks");
NetworkStatsService.nativeInitNetworkTracing();
}
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 468d7bd..93ccb85 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -26,6 +26,7 @@
import static android.net.nsd.NsdManager.MDNS_SERVICE_EVENT;
import static android.net.nsd.NsdManager.RESOLVE_SERVICE_SUCCEEDED;
import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
+
import static com.android.modules.utils.build.SdkLevel.isAtLeastU;
import static com.android.networkstack.apishim.ConstantsShim.REGISTER_NSD_OFFLOAD_ENGINE;
import static com.android.server.connectivity.mdns.MdnsAdvertiser.AdvertiserMetrics;
@@ -1709,7 +1710,7 @@
mMdnsSocketClient, LOGGER.forSubComponent("MdnsDiscoveryManager"));
handler.post(() -> mMdnsSocketClient.setCallback(mMdnsDiscoveryManager));
MdnsFeatureFlags flags = new MdnsFeatureFlags.Builder().setIsMdnsOffloadFeatureEnabled(
- mDeps.isTetheringFeatureNotChickenedOut(
+ mDeps.isTetheringFeatureNotChickenedOut(mContext,
MdnsFeatureFlags.NSD_FORCE_DISABLE_MDNS_OFFLOAD)).build();
mAdvertiser = deps.makeMdnsAdvertiser(handler.getLooper(), mMdnsSocketProvider,
new AdvertiserCallback(), LOGGER.forSubComponent("MdnsAdvertiser"), flags);
@@ -1763,8 +1764,8 @@
/**
* @see DeviceConfigUtils#isTetheringFeatureNotChickenedOut
*/
- public boolean isTetheringFeatureNotChickenedOut(String feature) {
- return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(feature);
+ public boolean isTetheringFeatureNotChickenedOut(Context context, String feature) {
+ return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context, feature);
}
/**
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 4b24aaf..6a34a24 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -254,7 +254,7 @@
if (sInitialized) return;
if (sEnableJavaBpfMap == null) {
sEnableJavaBpfMap = SdkLevel.isAtLeastU() ||
- DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+ DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context,
BPF_NET_MAPS_FORCE_DISABLE_JAVA_BPF_MAP);
}
Log.d(TAG, "BpfNetMaps is initialized with sEnableJavaBpfMap=" + sEnableJavaBpfMap);
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 3ae3e2d..b5dbf96 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -1427,7 +1427,7 @@
public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator(
@NonNull final Context context, @NonNull final TelephonyManager tm) {
if (isAtLeastT()) {
- return new CarrierPrivilegeAuthenticator(context, tm);
+ return new CarrierPrivilegeAuthenticator(context, this, tm);
} else {
return null;
}
@@ -4405,7 +4405,7 @@
updateCapabilitiesForNetwork(nai);
} else if (portalChanged) {
if (portal && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
- == getCaptivePortalMode()) {
+ == getCaptivePortalMode(nai)) {
if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
nai.onPreventAutomaticReconnect();
teardownUnneededNetwork(nai);
@@ -4441,7 +4441,13 @@
}
}
- private int getCaptivePortalMode() {
+ private int getCaptivePortalMode(@NonNull NetworkAgentInfo nai) {
+ if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) &&
+ mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)) {
+ // Do not avoid captive portal when network is wear proxy.
+ return ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT;
+ }
+
return Settings.Global.getInt(mContext.getContentResolver(),
ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE,
ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT);
diff --git a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
index 3befcfa..11345d3 100644
--- a/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/AutomaticOnOffKeepaliveTracker.java
@@ -974,7 +974,7 @@
* @return whether the feature is enabled
*/
public boolean isTetheringFeatureNotChickenedOut(@NonNull final String name) {
- return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(name);
+ return DeviceConfigUtils.isTetheringFeatureNotChickenedOut(mContext, name);
}
/**
diff --git a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
index 88aa329..ab7b1a7 100644
--- a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
+++ b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
@@ -16,10 +16,12 @@
package com.android.server.connectivity;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static com.android.server.connectivity.ConnectivityFlags.CARRIER_SERVICE_CHANGED_USE_CALLBACK;
+
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -44,6 +46,7 @@
import com.android.networkstack.apishim.common.TelephonyManagerShim;
import com.android.networkstack.apishim.common.TelephonyManagerShim.CarrierPrivilegesListenerShim;
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.server.ConnectivityService;
import java.util.ArrayList;
import java.util.List;
@@ -55,7 +58,7 @@
* carrier privileged app that provides the carrier config
* @hide
*/
-public class CarrierPrivilegeAuthenticator extends BroadcastReceiver {
+public class CarrierPrivilegeAuthenticator {
private static final String TAG = CarrierPrivilegeAuthenticator.class.getSimpleName();
private static final boolean DBG = true;
@@ -68,86 +71,96 @@
@GuardedBy("mLock")
private int mModemCount = 0;
private final Object mLock = new Object();
- private final HandlerThread mThread;
private final Handler mHandler;
@NonNull
- private final List<CarrierPrivilegesListenerShim> mCarrierPrivilegesChangedListeners =
- new ArrayList<>();
+ private final List<PrivilegeListener> mCarrierPrivilegesChangedListeners = new ArrayList<>();
+ private final boolean mUseCallbacksForServiceChanged;
public CarrierPrivilegeAuthenticator(@NonNull final Context c,
+ @NonNull final ConnectivityService.Dependencies deps,
@NonNull final TelephonyManager t,
@NonNull final TelephonyManagerShim telephonyManagerShim) {
mContext = c;
mTelephonyManager = t;
mTelephonyManagerShim = telephonyManagerShim;
- mThread = new HandlerThread(TAG);
- mThread.start();
- mHandler = new Handler(mThread.getLooper()) {};
+ final HandlerThread thread = new HandlerThread(TAG);
+ thread.start();
+ mHandler = new Handler(thread.getLooper());
+ mUseCallbacksForServiceChanged = deps.isFeatureEnabled(
+ c, CARRIER_SERVICE_CHANGED_USE_CALLBACK);
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED);
synchronized (mLock) {
- mModemCount = mTelephonyManager.getActiveModemCount();
- registerForCarrierChanges();
- updateCarrierServiceUid();
+ // Never unregistered because the system server never stops
+ c.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ switch (intent.getAction()) {
+ case TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED:
+ simConfigChanged();
+ break;
+ default:
+ Log.d(TAG, "Unknown intent received, action: " + intent.getAction());
+ }
+ }
+ }, filter, null, mHandler);
+ simConfigChanged();
}
}
public CarrierPrivilegeAuthenticator(@NonNull final Context c,
+ @NonNull final ConnectivityService.Dependencies deps,
@NonNull final TelephonyManager t) {
- this(c, t, TelephonyManagerShimImpl.newInstance(t));
+ this(c, deps, t, TelephonyManagerShimImpl.newInstance(t));
}
- /**
- * Broadcast receiver for ACTION_MULTI_SIM_CONFIG_CHANGED
- *
- * <p>The broadcast receiver is registered with mHandler
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- switch (intent.getAction()) {
- case TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED:
- handleActionMultiSimConfigChanged(context, intent);
- break;
- default:
- Log.d(TAG, "Unknown intent received with action: " + intent.getAction());
- }
- }
-
- private void handleActionMultiSimConfigChanged(Context context, Intent intent) {
- unregisterCarrierPrivilegesListeners();
+ private void simConfigChanged() {
synchronized (mLock) {
+ unregisterCarrierPrivilegesListeners();
mModemCount = mTelephonyManager.getActiveModemCount();
+ registerCarrierPrivilegesListeners(mModemCount);
+ if (!mUseCallbacksForServiceChanged) updateCarrierServiceUid();
}
- registerCarrierPrivilegesListeners();
- updateCarrierServiceUid();
}
- private void registerForCarrierChanges() {
- final IntentFilter filter = new IntentFilter();
- filter.addAction(TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED);
- mContext.registerReceiver(this, filter, null, mHandler);
- registerCarrierPrivilegesListeners();
+ private class PrivilegeListener implements CarrierPrivilegesListenerShim {
+ public final int mLogicalSlot;
+ PrivilegeListener(final int logicalSlot) {
+ mLogicalSlot = logicalSlot;
+ }
+
+ @Override public void onCarrierPrivilegesChanged(
+ @NonNull List<String> privilegedPackageNames,
+ @NonNull int[] privilegedUids) {
+ if (mUseCallbacksForServiceChanged) return;
+ // Re-trigger the synchronous check (which is also very cheap due
+ // to caching in CarrierPrivilegesTracker). This allows consistency
+ // with the onSubscriptionsChangedListener and broadcasts.
+ updateCarrierServiceUid();
+ }
+
+ @Override
+ public void onCarrierServiceChanged(@Nullable final String carrierServicePackageName,
+ final int carrierServiceUid) {
+ if (!mUseCallbacksForServiceChanged) {
+ // Re-trigger the synchronous check (which is also very cheap due
+ // to caching in CarrierPrivilegesTracker). This allows consistency
+ // with the onSubscriptionsChangedListener and broadcasts.
+ updateCarrierServiceUid();
+ return;
+ }
+ synchronized (mLock) {
+ mCarrierServiceUid.put(mLogicalSlot, carrierServiceUid);
+ }
+ }
}
- private void registerCarrierPrivilegesListeners() {
+ private void registerCarrierPrivilegesListeners(final int modemCount) {
final HandlerExecutor executor = new HandlerExecutor(mHandler);
- int modemCount;
- synchronized (mLock) {
- modemCount = mModemCount;
- }
try {
for (int i = 0; i < modemCount; i++) {
- CarrierPrivilegesListenerShim carrierPrivilegesListener =
- new CarrierPrivilegesListenerShim() {
- @Override
- public void onCarrierPrivilegesChanged(
- @NonNull List<String> privilegedPackageNames,
- @NonNull int[] privilegedUids) {
- // Re-trigger the synchronous check (which is also very cheap due
- // to caching in CarrierPrivilegesTracker). This allows consistency
- // with the onSubscriptionsChangedListener and broadcasts.
- updateCarrierServiceUid();
- }
- };
- addCarrierPrivilegesListener(i, executor, carrierPrivilegesListener);
+ PrivilegeListener carrierPrivilegesListener = new PrivilegeListener(i);
+ addCarrierPrivilegesListener(executor, carrierPrivilegesListener);
mCarrierPrivilegesChangedListeners.add(carrierPrivilegesListener);
}
} catch (IllegalArgumentException e) {
@@ -155,24 +168,13 @@
}
}
- private void addCarrierPrivilegesListener(int logicalSlotIndex, Executor executor,
- CarrierPrivilegesListenerShim listener) {
- try {
- mTelephonyManagerShim.addCarrierPrivilegesListener(
- logicalSlotIndex, executor, listener);
- } catch (UnsupportedApiLevelException unsupportedApiLevelException) {
- // Should not happen since CarrierPrivilegeAuthenticator is only used on T+
- Log.e(TAG, "addCarrierPrivilegesListener API is not available");
+ @GuardedBy("mLock")
+ private void unregisterCarrierPrivilegesListeners() {
+ for (PrivilegeListener carrierPrivilegesListener : mCarrierPrivilegesChangedListeners) {
+ removeCarrierPrivilegesListener(carrierPrivilegesListener);
+ mCarrierServiceUid.delete(carrierPrivilegesListener.mLogicalSlot);
}
- }
-
- private void removeCarrierPrivilegesListener(CarrierPrivilegesListenerShim listener) {
- try {
- mTelephonyManagerShim.removeCarrierPrivilegesListener(listener);
- } catch (UnsupportedApiLevelException unsupportedApiLevelException) {
- // Should not happen since CarrierPrivilegeAuthenticator is only used on T+
- Log.e(TAG, "removeCarrierPrivilegesListener API is not available");
- }
+ mCarrierPrivilegesChangedListeners.clear();
}
private String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
@@ -186,14 +188,6 @@
return null;
}
- private void unregisterCarrierPrivilegesListeners() {
- for (CarrierPrivilegesListenerShim carrierPrivilegesListener :
- mCarrierPrivilegesChangedListeners) {
- removeCarrierPrivilegesListener(carrierPrivilegesListener);
- }
- mCarrierPrivilegesChangedListeners.clear();
- }
-
/**
* Check if a UID is the carrier service app of the subscription ID in the provided capabilities
*
@@ -276,4 +270,26 @@
int getCarrierServicePackageUidForSlot(int slotId) {
return getUidForPackage(getCarrierServicePackageNameForLogicalSlot(slotId));
}
+
+ // Helper methods to avoid having to deal with UnsupportedApiLevelException.
+
+ private void addCarrierPrivilegesListener(@NonNull final Executor executor,
+ @NonNull final PrivilegeListener listener) {
+ try {
+ mTelephonyManagerShim.addCarrierPrivilegesListener(listener.mLogicalSlot, executor,
+ listener);
+ } catch (UnsupportedApiLevelException unsupportedApiLevelException) {
+ // Should not happen since CarrierPrivilegeAuthenticator is only used on T+
+ Log.e(TAG, "addCarrierPrivilegesListener API is not available");
+ }
+ }
+
+ private void removeCarrierPrivilegesListener(PrivilegeListener listener) {
+ try {
+ mTelephonyManagerShim.removeCarrierPrivilegesListener(listener);
+ } catch (UnsupportedApiLevelException unsupportedApiLevelException) {
+ // Should not happen since CarrierPrivilegeAuthenticator is only used on T+
+ Log.e(TAG, "removeCarrierPrivilegesListener API is not available");
+ }
+ }
}
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
index eb3e7ce..17de146 100644
--- a/service/src/com/android/server/connectivity/ClatCoordinator.java
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -78,7 +78,7 @@
@VisibleForTesting
static final int MTU_DELTA = 28;
@VisibleForTesting
- static final int CLAT_MAX_MTU = 65536;
+ static final int CLAT_MAX_MTU = 1500 + MTU_DELTA;
// This must match the interface prefix in clatd.c.
private static final String CLAT_PREFIX = "v4-";
@@ -673,7 +673,7 @@
throw new IOException("Detect MTU on " + tunIface + " failed: " + e);
}
final int mtu = adjustMtu(detectedMtu);
- Log.i(TAG, "ipv4 mtu is " + mtu);
+ Log.i(TAG, "detected ipv4 mtu of " + detectedMtu + " adjusted to " + mtu);
// Config tun interface mtu, address and bring up.
try {
diff --git a/service/src/com/android/server/connectivity/ConnectivityFlags.java b/service/src/com/android/server/connectivity/ConnectivityFlags.java
index 9039a14..5aac8f1 100644
--- a/service/src/com/android/server/connectivity/ConnectivityFlags.java
+++ b/service/src/com/android/server/connectivity/ConnectivityFlags.java
@@ -33,6 +33,10 @@
public static final String NO_REMATCH_ALL_REQUESTS_ON_REGISTER =
"no_rematch_all_requests_on_register";
+ @VisibleForTesting
+ public static final String CARRIER_SERVICE_CHANGED_USE_CALLBACK =
+ "carrier_service_changed_use_callback_version";
+
private boolean mNoRematchAllRequestsOnRegister;
/**
diff --git a/service/src/com/android/server/connectivity/KeepaliveTracker.java b/service/src/com/android/server/connectivity/KeepaliveTracker.java
index feba821..a51f09f 100644
--- a/service/src/com/android/server/connectivity/KeepaliveTracker.java
+++ b/service/src/com/android/server/connectivity/KeepaliveTracker.java
@@ -993,7 +993,7 @@
*/
public boolean isAddressTranslationEnabled(@NonNull Context context) {
return DeviceConfigUtils.isFeatureSupported(context, FEATURE_CLAT_ADDRESS_TRANSLATE)
- && DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+ && DeviceConfigUtils.isTetheringFeatureNotChickenedOut(context,
CONFIG_DISABLE_CLAT_ADDRESS_TRANSLATE);
}
}
diff --git a/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java b/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java
index 1714f28..27ca7b7 100644
--- a/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java
+++ b/staticlibs/device/com/android/net/module/util/DeviceConfigUtils.java
@@ -40,6 +40,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Supplier;
/**
* Utilities for modules to query {@link DeviceConfig} and flags.
@@ -73,6 +74,9 @@
sNetworkStackModuleVersion = -1;
}
+ private static final int FORCE_ENABLE_FEATURE_FLAG_VALUE = 1;
+ private static final int FORCE_DISABLE_FEATURE_FLAG_VALUE = -1;
+
private static volatile long sPackageVersion = -1;
private static long getPackageVersion(@NonNull final Context context) {
// sPackageVersion may be set by another thread just after this check, but querying the
@@ -189,9 +193,8 @@
*/
public static boolean isNetworkStackFeatureEnabled(@NonNull Context context,
@NonNull String name, boolean defaultEnabled) {
- final long packageVersion = getPackageVersion(context);
- return isFeatureEnabled(context, packageVersion, NAMESPACE_CONNECTIVITY, name,
- defaultEnabled);
+ return isFeatureEnabled(NAMESPACE_CONNECTIVITY, name, defaultEnabled,
+ () -> getPackageVersion(context));
}
/**
@@ -205,7 +208,7 @@
*
* If the feature is disabled by default and enabled by flag push, this method should be used.
* If the feature is enabled by default and disabled by flag push (kill switch),
- * {@link #isTetheringFeatureNotChickenedOut(String)} should be used.
+ * {@link #isTetheringFeatureNotChickenedOut(Context, String)} should be used.
*
* @param context The global context information about an app environment.
* @param name The name of the property to look up.
@@ -213,17 +216,24 @@
*/
public static boolean isTetheringFeatureEnabled(@NonNull Context context,
@NonNull String name) {
- final long packageVersion = getTetheringModuleVersion(context);
- return isFeatureEnabled(context, packageVersion, NAMESPACE_TETHERING, name,
- false /* defaultEnabled */);
+ return isFeatureEnabled(NAMESPACE_TETHERING, name, false /* defaultEnabled */,
+ () -> getTetheringModuleVersion(context));
}
- private static boolean isFeatureEnabled(@NonNull Context context, long packageVersion,
- @NonNull String namespace, String name, boolean defaultEnabled) {
- final int propertyVersion = getDeviceConfigPropertyInt(namespace, name,
- 0 /* default value */);
- return (propertyVersion == 0 && defaultEnabled)
- || (propertyVersion != 0 && packageVersion >= (long) propertyVersion);
+ private static boolean isFeatureEnabled(@NonNull String namespace,
+ String name, boolean defaultEnabled, Supplier<Long> packageVersionSupplier) {
+ final int flagValue = getDeviceConfigPropertyInt(namespace, name, 0 /* default value */);
+ switch (flagValue) {
+ case 0:
+ return defaultEnabled;
+ case FORCE_DISABLE_FEATURE_FLAG_VALUE:
+ return false;
+ case FORCE_ENABLE_FEATURE_FLAG_VALUE:
+ return true;
+ default:
+ final long packageVersion = packageVersionSupplier.get();
+ return packageVersion >= (long) flagValue;
+ }
}
// Guess the tethering module name based on the package prefix of the connectivity resources
@@ -334,42 +344,38 @@
}
/**
- * Check whether one specific experimental feature in specific namespace from
- * {@link DeviceConfig} is not disabled. Feature can be disabled by setting a non-zero
- * value in the property. If the feature is enabled by default and disabled by flag push
- * (kill switch), this method should be used. If the feature is disabled by default and
- * enabled by flag push, {@link #isFeatureEnabled} should be used.
- *
- * @param namespace The namespace containing the property to look up.
- * @param name The name of the property to look up.
- * @return true if this feature is enabled, or false if disabled.
- */
- private static boolean isFeatureNotChickenedOut(String namespace, String name) {
- final int propertyVersion = getDeviceConfigPropertyInt(namespace, name,
- 0 /* default value */);
- return propertyVersion == 0;
- }
-
- /**
* Check whether one specific experimental feature in Tethering module from {@link DeviceConfig}
* is not disabled.
+ * If the feature is enabled by default and disabled by flag push (kill switch), this method
+ * should be used.
+ * If the feature is disabled by default and enabled by flag push,
+ * {@link #isTetheringFeatureEnabled(Context, String)} should be used.
*
+ * @param context The global context information about an app environment.
* @param name The name of the property in tethering module to look up.
* @return true if this feature is enabled, or false if disabled.
*/
- public static boolean isTetheringFeatureNotChickenedOut(String name) {
- return isFeatureNotChickenedOut(NAMESPACE_TETHERING, name);
+ public static boolean isTetheringFeatureNotChickenedOut(@NonNull Context context, String name) {
+ return isFeatureEnabled(NAMESPACE_TETHERING, name, true /* defaultEnabled */,
+ () -> getTetheringModuleVersion(context));
}
/**
* Check whether one specific experimental feature in NetworkStack module from
* {@link DeviceConfig} is not disabled.
+ * If the feature is enabled by default and disabled by flag push (kill switch), this method
+ * should be used.
+ * If the feature is disabled by default and enabled by flag push,
+ * {@link #isNetworkStackFeatureEnabled(Context, String)} should be used.
*
+ * @param context The global context information about an app environment.
* @param name The name of the property in NetworkStack module to look up.
* @return true if this feature is enabled, or false if disabled.
*/
- public static boolean isNetworkStackFeatureNotChickenedOut(String name) {
- return isFeatureNotChickenedOut(NAMESPACE_CONNECTIVITY, name);
+ public static boolean isNetworkStackFeatureNotChickenedOut(
+ @NonNull Context context, String name) {
+ return isFeatureEnabled(NAMESPACE_CONNECTIVITY, name, true /* defaultEnabled */,
+ () -> getPackageVersion(context));
}
/**
diff --git a/staticlibs/native/bpf_headers/BpfMapTest.cpp b/staticlibs/native/bpf_headers/BpfMapTest.cpp
index 10afe86..862114d 100644
--- a/staticlibs/native/bpf_headers/BpfMapTest.cpp
+++ b/staticlibs/native/bpf_headers/BpfMapTest.cpp
@@ -107,12 +107,14 @@
BpfMap<uint32_t, uint32_t> testMap1;
checkMapInvalid(testMap1);
- BpfMap<uint32_t, uint32_t> testMap2(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap2;
+ ASSERT_RESULT_OK(testMap2.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
checkMapValid(testMap2);
}
TEST_F(BpfMapTest, basicHelpers) {
- BpfMap<uint32_t, uint32_t> testMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap;
+ ASSERT_RESULT_OK(testMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
uint32_t key = TEST_KEY1;
uint32_t value_write = TEST_VALUE1;
writeToMapAndCheck(testMap, key, value_write);
@@ -126,7 +128,8 @@
}
TEST_F(BpfMapTest, reset) {
- BpfMap<uint32_t, uint32_t> testMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap;
+ ASSERT_RESULT_OK(testMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
uint32_t key = TEST_KEY1;
uint32_t value_write = TEST_VALUE1;
writeToMapAndCheck(testMap, key, value_write);
@@ -138,7 +141,8 @@
}
TEST_F(BpfMapTest, moveConstructor) {
- BpfMap<uint32_t, uint32_t> testMap1(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap1;
+ ASSERT_RESULT_OK(testMap1.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
BpfMap<uint32_t, uint32_t> testMap2;
testMap2 = std::move(testMap1);
uint32_t key = TEST_KEY1;
@@ -149,7 +153,8 @@
TEST_F(BpfMapTest, SetUpMap) {
EXPECT_NE(0, access(PINNED_MAP_PATH, R_OK));
- BpfMap<uint32_t, uint32_t> testMap1(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap1;
+ ASSERT_RESULT_OK(testMap1.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
ASSERT_EQ(0, bpfFdPin(testMap1.getMap(), PINNED_MAP_PATH));
EXPECT_EQ(0, access(PINNED_MAP_PATH, R_OK));
checkMapValid(testMap1);
@@ -164,7 +169,8 @@
}
TEST_F(BpfMapTest, iterate) {
- BpfMap<uint32_t, uint32_t> testMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap;
+ ASSERT_RESULT_OK(testMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
populateMap(TEST_MAP_SIZE, testMap);
int totalCount = 0;
int totalSum = 0;
@@ -182,7 +188,8 @@
}
TEST_F(BpfMapTest, iterateWithValue) {
- BpfMap<uint32_t, uint32_t> testMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap;
+ ASSERT_RESULT_OK(testMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
populateMap(TEST_MAP_SIZE, testMap);
int totalCount = 0;
int totalSum = 0;
@@ -202,7 +209,8 @@
}
TEST_F(BpfMapTest, mapIsEmpty) {
- BpfMap<uint32_t, uint32_t> testMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap;
+ ASSERT_RESULT_OK(testMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC));
expectMapEmpty(testMap);
uint32_t key = TEST_KEY1;
uint32_t value_write = TEST_VALUE1;
@@ -232,7 +240,8 @@
}
TEST_F(BpfMapTest, mapClear) {
- BpfMap<uint32_t, uint32_t> testMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, BPF_F_NO_PREALLOC);
+ BpfMap<uint32_t, uint32_t> testMap;
+ ASSERT_RESULT_OK(testMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE));
populateMap(TEST_MAP_SIZE, testMap);
Result<bool> isEmpty = testMap.isEmpty();
ASSERT_RESULT_OK(isEmpty);
diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfMap.h b/staticlibs/native/bpf_headers/include/bpf/BpfMap.h
index 3be7067..5d7eb0d 100644
--- a/staticlibs/native/bpf_headers/include/bpf/BpfMap.h
+++ b/staticlibs/native/bpf_headers/include/bpf/BpfMap.h
@@ -48,41 +48,32 @@
// is not safe to iterate over a map while another thread or process is deleting
// from it. In this case the iteration can return duplicate entries.
template <class Key, class Value>
-class BpfMap {
+class BpfMapRO {
public:
- BpfMap<Key, Value>() {};
+ BpfMapRO<Key, Value>() {};
// explicitly force no copy constructor, since it would need to dup the fd
// (later on, for testing, we still make available a copy assignment operator)
- BpfMap<Key, Value>(const BpfMap<Key, Value>&) = delete;
+ BpfMapRO<Key, Value>(const BpfMapRO<Key, Value>&) = delete;
- private:
- void abortOnKeyOrValueSizeMismatch() {
+ protected:
+ void abortOnMismatch(bool writable) const {
if (!mMapFd.ok()) abort();
if (isAtLeastKernelVersion(4, 14, 0)) {
+ int flags = bpfGetFdMapFlags(mMapFd);
+ if (flags < 0) abort();
+ if (flags & BPF_F_WRONLY) abort();
+ if (writable && (flags & BPF_F_RDONLY)) abort();
if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort();
if (bpfGetFdValueSize(mMapFd) != sizeof(Value)) abort();
}
}
- protected:
- // flag must be within BPF_OBJ_FLAG_MASK, ie. 0, BPF_F_RDONLY, BPF_F_WRONLY
- BpfMap<Key, Value>(const char* pathname, uint32_t flags) {
- mMapFd.reset(mapRetrieve(pathname, flags));
- abortOnKeyOrValueSizeMismatch();
- }
-
public:
- explicit BpfMap<Key, Value>(const char* pathname) : BpfMap<Key, Value>(pathname, 0) {}
-
-#ifdef BPF_MAP_MAKE_VISIBLE_FOR_TESTING
- // All bpf maps should be created by the bpfloader, so this constructor
- // is reserved for tests
- BpfMap<Key, Value>(bpf_map_type map_type, uint32_t max_entries, uint32_t map_flags = 0) {
- mMapFd.reset(createMap(map_type, sizeof(Key), sizeof(Value), max_entries, map_flags));
- if (!mMapFd.ok()) abort();
+ explicit BpfMapRO<Key, Value>(const char* pathname) {
+ mMapFd.reset(mapRetrieveRO(pathname));
+ abortOnMismatch(/* writable */ false);
}
-#endif
Result<Key> getFirstKey() const {
Key firstKey;
@@ -100,13 +91,6 @@
return nextKey;
}
- Result<void> writeValue(const Key& key, const Value& value, uint64_t flags) {
- if (writeToMapEntry(mMapFd, &key, &value, flags)) {
- return ErrnoErrorf("Write to map {} failed", mMapFd.get());
- }
- return {};
- }
-
Result<Value> readValue(const Key key) const {
Value value;
if (findMapEntry(mMapFd, &key, &value)) {
@@ -115,6 +99,155 @@
return value;
}
+ protected:
+ [[clang::reinitializes]] Result<void> init(const char* path, int fd, bool writable) {
+ mMapFd.reset(fd);
+ if (!mMapFd.ok()) {
+ return ErrnoErrorf("Pinned map not accessible or does not exist: ({})", path);
+ }
+ // Normally we should return an error here instead of calling abort,
+ // but this cannot happen at runtime without a massive code bug (K/V type mismatch)
+ // and as such it's better to just blow the system up and let the developer fix it.
+ // Crashes are much more likely to be noticed than logs and missing functionality.
+ abortOnMismatch(writable);
+ return {};
+ }
+
+ public:
+ // Function that tries to get map from a pinned path.
+ [[clang::reinitializes]] Result<void> init(const char* path) {
+ return init(path, mapRetrieveRO(path), /* writable */ false);
+ }
+
+ // Iterate through the map and handle each key retrieved based on the filter
+ // without modification of map content.
+ Result<void> iterate(
+ const function<Result<void>(const Key& key,
+ const BpfMapRO<Key, Value>& map)>& filter) const;
+
+ // Iterate through the map and get each <key, value> pair, handle each <key,
+ // value> pair based on the filter without modification of map content.
+ Result<void> iterateWithValue(
+ const function<Result<void>(const Key& key, const Value& value,
+ const BpfMapRO<Key, Value>& map)>& filter) const;
+
+#ifdef BPF_MAP_MAKE_VISIBLE_FOR_TESTING
+ const unique_fd& getMap() const { return mMapFd; };
+
+ // Copy assignment operator - due to need for fd duping, should not be used in non-test code.
+ BpfMapRO<Key, Value>& operator=(const BpfMapRO<Key, Value>& other) {
+ if (this != &other) mMapFd.reset(fcntl(other.mMapFd.get(), F_DUPFD_CLOEXEC, 0));
+ return *this;
+ }
+#else
+ BpfMapRO<Key, Value>& operator=(const BpfMapRO<Key, Value>&) = delete;
+#endif
+
+ // Move assignment operator
+ BpfMapRO<Key, Value>& operator=(BpfMapRO<Key, Value>&& other) noexcept {
+ if (this != &other) {
+ mMapFd = std::move(other.mMapFd);
+ other.reset();
+ }
+ return *this;
+ }
+
+#ifdef BPF_MAP_MAKE_VISIBLE_FOR_TESTING
+ // Note that unique_fd.reset() carefully saves and restores the errno,
+ // and BpfMap.reset() won't touch the errno if passed in fd is negative either,
+ // hence you can do something like BpfMap.reset(systemcall()) and then
+ // check BpfMap.isValid() and look at errno and see why systemcall() failed.
+ [[clang::reinitializes]] void reset(int fd) {
+ mMapFd.reset(fd);
+ if (mMapFd.ok()) abortOnMismatch(/* writable */ false); // false isn't ideal
+ }
+
+ // unique_fd has an implicit int conversion defined, which combined with the above
+ // reset(int) would result in double ownership of the fd, hence we either need a custom
+ // implementation of reset(unique_fd), or to delete it and thus cause compile failures
+ // to catch this and prevent it.
+ void reset(unique_fd fd) = delete;
+#endif
+
+ [[clang::reinitializes]] void reset() {
+ mMapFd.reset();
+ }
+
+ bool isValid() const { return mMapFd.ok(); }
+
+ Result<bool> isEmpty() const {
+ auto key = getFirstKey();
+ if (key.ok()) return false;
+ if (key.error().code() == ENOENT) return true;
+ return key.error();
+ }
+
+ protected:
+ unique_fd mMapFd;
+};
+
+template <class Key, class Value>
+Result<void> BpfMapRO<Key, Value>::iterate(
+ const function<Result<void>(const Key& key,
+ const BpfMapRO<Key, Value>& map)>& filter) const {
+ Result<Key> curKey = getFirstKey();
+ while (curKey.ok()) {
+ const Result<Key>& nextKey = getNextKey(curKey.value());
+ Result<void> status = filter(curKey.value(), *this);
+ if (!status.ok()) return status;
+ curKey = nextKey;
+ }
+ if (curKey.error().code() == ENOENT) return {};
+ return curKey.error();
+}
+
+template <class Key, class Value>
+Result<void> BpfMapRO<Key, Value>::iterateWithValue(
+ const function<Result<void>(const Key& key, const Value& value,
+ const BpfMapRO<Key, Value>& map)>& filter) const {
+ Result<Key> curKey = getFirstKey();
+ while (curKey.ok()) {
+ const Result<Key>& nextKey = getNextKey(curKey.value());
+ Result<Value> curValue = readValue(curKey.value());
+ if (!curValue.ok()) return curValue.error();
+ Result<void> status = filter(curKey.value(), curValue.value(), *this);
+ if (!status.ok()) return status;
+ curKey = nextKey;
+ }
+ if (curKey.error().code() == ENOENT) return {};
+ return curKey.error();
+}
+
+template <class Key, class Value>
+class BpfMap : public BpfMapRO<Key, Value> {
+ protected:
+ using BpfMapRO<Key, Value>::mMapFd;
+ using BpfMapRO<Key, Value>::abortOnMismatch;
+
+ public:
+ using BpfMapRO<Key, Value>::getFirstKey;
+ using BpfMapRO<Key, Value>::getNextKey;
+ using BpfMapRO<Key, Value>::readValue;
+
+ BpfMap<Key, Value>() {};
+
+ explicit BpfMap<Key, Value>(const char* pathname) {
+ mMapFd.reset(mapRetrieveRW(pathname));
+ abortOnMismatch(/* writable */ true);
+ }
+
+ // Function that tries to get map from a pinned path.
+ [[clang::reinitializes]] Result<void> init(const char* path) {
+ return BpfMapRO<Key,Value>::init(path, mapRetrieveRW(path), /* writable */ true);
+ }
+
+ Result<void> writeValue(const Key& key, const Value& value, uint64_t flags) {
+ if (writeToMapEntry(mMapFd, &key, &value, flags)) {
+ return ErrnoErrorf("Write to map {} failed", mMapFd.get());
+ }
+ return {};
+ }
+
Result<void> deleteValue(const Key& key) {
if (deleteMapEntry(mMapFd, &key)) {
return ErrnoErrorf("Delete entry from map {} failed", mMapFd.get());
@@ -122,37 +255,33 @@
return {};
}
- protected:
- [[clang::reinitializes]] Result<void> init(const char* path, int fd) {
- mMapFd.reset(fd);
- if (!mMapFd.ok()) {
- return ErrnoErrorf("Pinned map not accessible or does not exist: ({})", path);
+ Result<void> clear() {
+ while (true) {
+ auto key = getFirstKey();
+ if (!key.ok()) {
+ if (key.error().code() == ENOENT) return {}; // empty: success
+ return key.error(); // Anything else is an error
+ }
+ auto res = deleteValue(key.value());
+ if (!res.ok()) {
+ // Someone else could have deleted the key, so ignore ENOENT
+ if (res.error().code() == ENOENT) continue;
+ ALOGE("Failed to delete data %s", strerror(res.error().code()));
+ return res.error();
+ }
}
- // Normally we should return an error here instead of calling abort,
- // but this cannot happen at runtime without a massive code bug (K/V type mismatch)
- // and as such it's better to just blow the system up and let the developer fix it.
- // Crashes are much more likely to be noticed than logs and missing functionality.
- abortOnKeyOrValueSizeMismatch();
- return {};
}
- public:
- // Function that tries to get map from a pinned path.
- [[clang::reinitializes]] Result<void> init(const char* path) {
- return init(path, mapRetrieveRW(path));
- }
-
-
#ifdef BPF_MAP_MAKE_VISIBLE_FOR_TESTING
- // due to Android SELinux limitations which prevent map creation by anyone besides the bpfloader
- // this should only ever be used by test code, it is equivalent to:
- // .reset(createMap(type, keysize, valuesize, max_entries, map_flags)
- // TODO: derive map_flags from BpfMap vs BpfMapRO
[[clang::reinitializes]] Result<void> resetMap(bpf_map_type map_type,
- uint32_t max_entries,
- uint32_t map_flags = 0) {
- mMapFd.reset(createMap(map_type, sizeof(Key), sizeof(Value), max_entries, map_flags));
+ uint32_t max_entries,
+ uint32_t map_flags = 0) {
+ if (map_flags & BPF_F_WRONLY) abort();
+ if (map_flags & BPF_F_RDONLY) abort();
+ mMapFd.reset(createMap(map_type, sizeof(Key), sizeof(Value), max_entries,
+ map_flags));
if (!mMapFd.ok()) return ErrnoErrorf("Unable to create map.");
+ abortOnMismatch(/* writable */ true);
return {};
}
#endif
@@ -180,72 +309,6 @@
const function<Result<void>(const Key& key, const Value& value,
BpfMap<Key, Value>& map)>& filter);
-#ifdef BPF_MAP_MAKE_VISIBLE_FOR_TESTING
- const unique_fd& getMap() const { return mMapFd; };
-
- // Copy assignment operator - due to need for fd duping, should not be used in non-test code.
- BpfMap<Key, Value>& operator=(const BpfMap<Key, Value>& other) {
- if (this != &other) mMapFd.reset(fcntl(other.mMapFd.get(), F_DUPFD_CLOEXEC, 0));
- return *this;
- }
-#else
- BpfMap<Key, Value>& operator=(const BpfMap<Key, Value>&) = delete;
-#endif
-
- // Move assignment operator
- BpfMap<Key, Value>& operator=(BpfMap<Key, Value>&& other) noexcept {
- if (this != &other) {
- mMapFd = std::move(other.mMapFd);
- other.reset();
- }
- return *this;
- }
-
- void reset(unique_fd fd) = delete;
-
-#ifdef BPF_MAP_MAKE_VISIBLE_FOR_TESTING
- // Note that unique_fd.reset() carefully saves and restores the errno,
- // and BpfMap.reset() won't touch the errno if passed in fd is negative either,
- // hence you can do something like BpfMap.reset(systemcall()) and then
- // check BpfMap.isValid() and look at errno and see why systemcall() failed.
- [[clang::reinitializes]] void reset(int fd) {
- mMapFd.reset(fd);
- if (mMapFd.ok()) abortOnKeyOrValueSizeMismatch();
- }
-#endif
-
- [[clang::reinitializes]] void reset() {
- mMapFd.reset();
- }
-
- bool isValid() const { return mMapFd.ok(); }
-
- Result<void> clear() {
- while (true) {
- auto key = getFirstKey();
- if (!key.ok()) {
- if (key.error().code() == ENOENT) return {}; // empty: success
- return key.error(); // Anything else is an error
- }
- auto res = deleteValue(key.value());
- if (!res.ok()) {
- // Someone else could have deleted the key, so ignore ENOENT
- if (res.error().code() == ENOENT) continue;
- ALOGE("Failed to delete data %s", strerror(res.error().code()));
- return res.error();
- }
- }
- }
-
- Result<bool> isEmpty() const {
- auto key = getFirstKey();
- if (key.ok()) return false;
- if (key.error().code() == ENOENT) return true;
- return key.error();
- }
-
- private:
- unique_fd mMapFd;
};
template <class Key, class Value>
@@ -312,19 +375,5 @@
return curKey.error();
}
-template <class Key, class Value>
-class BpfMapRO : public BpfMap<Key, Value> {
- public:
- BpfMapRO<Key, Value>() {};
-
- explicit BpfMapRO<Key, Value>(const char* pathname)
- : BpfMap<Key, Value>(pathname, BPF_F_RDONLY) {}
-
- // Function that tries to get map from a pinned path.
- [[clang::reinitializes]] Result<void> init(const char* path) {
- return BpfMap<Key,Value>::init(path, mapRetrieveRO(path));
- }
-};
-
} // namespace bpf
} // namespace android
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java
index befd751..75b6250 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/DeviceConfigUtilsTest.java
@@ -232,27 +232,57 @@
}
@Test
- public void testIsNetworkStackFeatureEnabled() {
+ public void testIsFeatureEnabled() {
doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
TEST_EXPERIMENT_FLAG));
- assertTrue(DeviceConfigUtils.isNetworkStackFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
- }
-
- @Test
- public void testIsTetheringFeatureEnabled() {
doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isNetworkStackFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
}
-
@Test
- public void testFeatureDefaultEnabled() {
+ public void testIsFeatureEnabledFeatureDefaultDisabled() throws Exception {
doReturn(null).when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
TEST_EXPERIMENT_FLAG));
doReturn(null).when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
TEST_EXPERIMENT_FLAG));
assertFalse(DeviceConfigUtils.isNetworkStackFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
assertFalse(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
+
+ // If the flag is unset, package info is not queried
+ verify(mContext, never()).getPackageManager();
+ verify(mContext, never()).getPackageName();
+ verify(mPm, never()).getPackageInfo(anyString(), anyInt());
+ }
+
+ @Test
+ public void testIsFeatureEnabledFeatureForceEnabled() throws Exception {
+ doReturn("1").when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
+ TEST_EXPERIMENT_FLAG));
+ doReturn("1").when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
+ TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isNetworkStackFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
+
+ // If the feature is force enabled, package info is not queried
+ verify(mContext, never()).getPackageManager();
+ verify(mContext, never()).getPackageName();
+ verify(mPm, never()).getPackageInfo(anyString(), anyInt());
+ }
+
+ @Test
+ public void testIsFeatureEnabledFeatureForceDisabled() throws Exception {
+ doReturn("-1").when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
+ TEST_EXPERIMENT_FLAG));
+ doReturn("-1").when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
+ TEST_EXPERIMENT_FLAG));
+ assertFalse(DeviceConfigUtils.isNetworkStackFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
+ assertFalse(DeviceConfigUtils.isTetheringFeatureEnabled(mContext, TEST_EXPERIMENT_FLAG));
+
+ // If the feature is force disabled, package info is not queried
+ verify(mContext, never()).getPackageManager();
+ verify(mContext, never()).getPackageName();
+ verify(mPm, never()).getPackageInfo(anyString(), anyInt());
}
@Test
@@ -419,26 +449,66 @@
}
@Test
- public void testIsTetheringFeatureNotChickenedOut() throws Exception {
- doReturn("0").when(() -> DeviceConfig.getProperty(
- eq(NAMESPACE_TETHERING), eq(TEST_EXPERIMENT_FLAG)));
- assertTrue(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG));
-
- doReturn(TEST_FLAG_VALUE_STRING).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_TETHERING), eq(TEST_EXPERIMENT_FLAG)));
- assertFalse(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG));
+ public void testIsFeatureNotChickenedOut() {
+ doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
+ TEST_EXPERIMENT_FLAG));
+ doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
+ TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
}
@Test
- public void testIsNetworkStackFeatureNotChickenedOut() throws Exception {
- doReturn("0").when(() -> DeviceConfig.getProperty(
- eq(NAMESPACE_CONNECTIVITY), eq(TEST_EXPERIMENT_FLAG)));
- assertTrue(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG));
+ public void testIsFeatureNotChickenedOutFeatureDefaultEnabled() throws Exception {
+ doReturn(null).when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
+ TEST_EXPERIMENT_FLAG));
+ doReturn(null).when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
+ TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
- doReturn(TEST_FLAG_VALUE_STRING).when(
- () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
- eq(TEST_EXPERIMENT_FLAG)));
- assertFalse(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(TEST_EXPERIMENT_FLAG));
+ // If the flag is unset, package info is not queried
+ verify(mContext, never()).getPackageManager();
+ verify(mContext, never()).getPackageName();
+ verify(mPm, never()).getPackageInfo(anyString(), anyInt());
+ }
+
+ @Test
+ public void testIsFeatureNotChickenedOutFeatureForceEnabled() throws Exception {
+ doReturn("1").when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
+ TEST_EXPERIMENT_FLAG));
+ doReturn("1").when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
+ TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
+ assertTrue(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
+
+ // If the feature is force enabled, package info is not queried
+ verify(mContext, never()).getPackageManager();
+ verify(mContext, never()).getPackageName();
+ verify(mPm, never()).getPackageInfo(anyString(), anyInt());
+ }
+
+ @Test
+ public void testIsFeatureNotChickenedOutFeatureForceDisabled() throws Exception {
+ doReturn("-1").when(() -> DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY,
+ TEST_EXPERIMENT_FLAG));
+ doReturn("-1").when(() -> DeviceConfig.getProperty(NAMESPACE_TETHERING,
+ TEST_EXPERIMENT_FLAG));
+ assertFalse(DeviceConfigUtils.isNetworkStackFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
+ assertFalse(DeviceConfigUtils.isTetheringFeatureNotChickenedOut(
+ mContext, TEST_EXPERIMENT_FLAG));
+
+ // If the feature is force disabled, package info is not queried
+ verify(mContext, never()).getPackageManager();
+ verify(mContext, never()).getPackageName();
+ verify(mPm, never()).getPackageInfo(anyString(), anyInt());
}
@Test
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java
index 3a72dd1..5e9b004 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/NetlinkUtilsTest.java
@@ -88,6 +88,11 @@
if (SdkLevel.isAtLeastT() && targetSdk > 31) {
var ctxt = new String(Files.readAllBytes(Paths.get("/proc/thread-self/attr/current")));
assumeFalse("must not be platform app", ctxt.startsWith("u:r:platform_app:s0:"));
+ // NetworkStackCoverageTests uses the same UID with NetworkStack module, which
+ // still has the permission to send RTM_GETNEIGH message (sepolicy just blocks the
+ // access from untrusted_apps), also exclude the NetworkStackCoverageTests.
+ assumeFalse("network_stack context is expected to have permission to send RTM_GETNEIGH",
+ ctxt.startsWith("u:r:network_stack:s0"));
try {
NetlinkUtils.sendMessage(fd, req, 0, req.length, TEST_TIMEOUT_MS);
fail("RTM_GETNEIGH is not allowed for apps targeting SDK > 31 on T+ platforms,"
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRunner.kt b/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRunner.kt
index 2e73666..2d281fd 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRunner.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/DevSdkIgnoreRunner.kt
@@ -19,6 +19,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import java.lang.reflect.Modifier
import org.junit.runner.Description
import org.junit.runner.Runner
import org.junit.runner.manipulation.Filter
@@ -27,7 +28,7 @@
import org.junit.runner.manipulation.Sortable
import org.junit.runner.manipulation.Sorter
import org.junit.runner.notification.RunNotifier
-import kotlin.jvm.Throws
+import org.junit.runners.Parameterized
/**
* A runner that can skip tests based on the development SDK as defined in [DevSdkIgnoreRule].
@@ -41,6 +42,9 @@
* the whole class if they do not match the development SDK as defined in [DevSdkIgnoreRule].
* Otherwise, it will delegate to [AndroidJUnit4] to run the test as usual.
*
+ * This class automatically uses the Parameterized runner as its base runner when needed, so the
+ * @Parameterized.Parameters annotation and its friends can be used in tests using this runner.
+ *
* Example usage:
*
* @RunWith(DevSdkIgnoreRunner::class)
@@ -48,13 +52,34 @@
* class MyTestClass { ... }
*/
class DevSdkIgnoreRunner(private val klass: Class<*>) : Runner(), Filterable, Sortable {
- private val baseRunner = klass.let {
+ // Inference correctly infers Runner & Filterable & Sortable for |baseRunner|, but the
+ // Java bytecode doesn't have a way to express this. Give this type a name by wrapping it.
+ private class RunnerWrapper<T>(private val wrapped: T) :
+ Runner(), Filterable by wrapped, Sortable by wrapped
+ where T : Runner, T : Filterable, T : Sortable {
+ override fun getDescription(): Description = wrapped.description
+ override fun run(notifier: RunNotifier?) = wrapped.run(notifier)
+ }
+
+ private val baseRunner: RunnerWrapper<*>? = klass.let {
val ignoreAfter = it.getAnnotation(IgnoreAfter::class.java)
val ignoreUpTo = it.getAnnotation(IgnoreUpTo::class.java)
- if (isDevSdkInRange(ignoreUpTo, ignoreAfter)) AndroidJUnit4(klass) else null
+ if (!isDevSdkInRange(ignoreUpTo, ignoreAfter)) {
+ null
+ } else if (it.hasParameterizedMethod()) {
+ // Parameterized throws if there is no static method annotated with @Parameters, which
+ // isn't too useful. Use it if there are, otherwise use its base AndroidJUnit4 runner.
+ RunnerWrapper(Parameterized(klass))
+ } else {
+ RunnerWrapper(AndroidJUnit4(klass))
+ }
}
+ private fun <T> Class<T>.hasParameterizedMethod(): Boolean = methods.any {
+ Modifier.isStatic(it.modifiers) &&
+ it.isAnnotationPresent(Parameterized.Parameters::class.java) }
+
override fun run(notifier: RunNotifier) {
if (baseRunner != null) {
baseRunner.run(notifier)
@@ -88,4 +113,4 @@
override fun sort(sorter: Sorter?) {
baseRunner?.sort(sorter)
}
-}
\ No newline at end of file
+}
diff --git a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
index 7bccbde..6a019b7 100644
--- a/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/NetworkStatsManagerTest.java
@@ -387,6 +387,7 @@
now = System.currentTimeMillis();
}
}
+ mCm.unregisterNetworkCallback(callback);
if (callback.success) {
mNetworkInterfacesToTest[networkTypeIndex].setMetered(callback.metered);
mNetworkInterfacesToTest[networkTypeIndex].setRoaming(callback.roaming);
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt
index c2bb7cd..f374181 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerDownstreamTetheringTest.kt
@@ -23,6 +23,7 @@
import android.net.TetheringManager.TetheringRequest
import android.net.nsd.NsdManager
import android.os.Build
+import android.platform.test.annotations.AppModeFull
import androidx.test.filters.SmallTest
import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule
@@ -41,6 +42,7 @@
@RunWith(DevSdkIgnoreRunner::class)
@SmallTest
@ConnectivityModuleTest
+@AppModeFull(reason = "WifiManager cannot be obtained in instant mode")
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
class NsdManagerDownstreamTetheringTest : EthernetTetheringTestBase() {
private val nsdManager by lazy { context.getSystemService(NsdManager::class.java)!! }
diff --git a/tests/cts/net/src/android/net/cts/RateLimitTest.java b/tests/cts/net/src/android/net/cts/RateLimitTest.java
index 5c93738..36b98fc 100644
--- a/tests/cts/net/src/android/net/cts/RateLimitTest.java
+++ b/tests/cts/net/src/android/net/cts/RateLimitTest.java
@@ -36,7 +36,6 @@
import android.icu.text.MessageFormat;
import android.net.ConnectivityManager;
import android.net.ConnectivitySettingsManager;
-import android.net.ConnectivityThread;
import android.net.InetAddresses;
import android.net.IpPrefix;
import android.net.LinkAddress;
@@ -190,19 +189,7 @@
// whatever happens, don't leave the device in rate limited state.
ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond(mContext, -1);
}
- if (mSocket == null) {
- // HACK(b/272147742): dump ConnectivityThread if test initialization failed.
- final StackTraceElement[] elements = ConnectivityThread.get().getStackTrace();
- final StringBuilder sb = new StringBuilder();
- // Skip first element as it includes the invocation of getStackTrace()
- for (int i = 1; i < elements.length; i++) {
- sb.append(elements[i]);
- sb.append("\n");
- }
- Log.e(TAG, sb.toString());
- } else {
- mSocket.close();
- }
+ if (mSocket != null) mSocket.close();
if (mNetworkAgent != null) mNetworkAgent.unregister();
if (mTunInterface != null) mTunInterface.getFileDescriptor().close();
if (mCm != null) mCm.unregisterNetworkCallback(mNetworkCallback);
diff --git a/tests/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/integration/util/com/android/server/NetworkAgentWrapper.java
index edd201d..ec09f9e 100644
--- a/tests/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -19,6 +19,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
+import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
@@ -123,6 +124,10 @@
mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
mNetworkCapabilities.addTransportType(transport);
switch (transport) {
+ case TRANSPORT_BLUETOOTH:
+ // Score for Wear companion proxy network; not BLUETOOTH tethering.
+ mScore = new NetworkScore.Builder().setLegacyInt(100).build();
+ break;
case TRANSPORT_ETHERNET:
mScore = new NetworkScore.Builder().setLegacyInt(70).build();
break;
diff --git a/tests/mts/bpf_existence_test.cpp b/tests/mts/bpf_existence_test.cpp
index 15263cc..0c424e9 100644
--- a/tests/mts/bpf_existence_test.cpp
+++ b/tests/mts/bpf_existence_test.cpp
@@ -129,6 +129,16 @@
SHARED "prog_dscpPolicy_schedcls_set_dscp_ether",
};
+// Provided by *current* mainline module for U+ devices
+static const set<string> MAINLINE_FOR_U_PLUS = {
+ NETD "map_netd_packet_trace_enabled_map",
+};
+
+// Provided by *current* mainline module for U+ devices with 5.10+ kernels
+static const set<string> MAINLINE_FOR_U_5_10_PLUS = {
+ NETD "map_netd_packet_trace_ringbuf",
+};
+
static void addAll(set<string>& a, const set<string>& b) {
a.insert(b.begin(), b.end());
}
@@ -171,6 +181,8 @@
// U requires Linux Kernel 4.14+, but nothing (as yet) added or removed in U.
if (IsAtLeastU()) ASSERT_TRUE(isAtLeastKernelVersion(4, 14, 0));
+ DO_EXPECT(IsAtLeastU(), MAINLINE_FOR_U_PLUS);
+ DO_EXPECT(IsAtLeastU() && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_U_5_10_PLUS);
// V requires Linux Kernel 4.19+, but nothing (as yet) added or removed in V.
if (IsAtLeastV()) ASSERT_TRUE(isAtLeastKernelVersion(4, 19, 0));
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index c8cbce1..eb03157 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -30,6 +30,7 @@
import static android.Manifest.permission.NETWORK_SETUP_WIZARD;
import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD;
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN;
import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_UNFROZEN;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
@@ -128,6 +129,7 @@
import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
import static android.net.NetworkCapabilities.REDACT_NONE;
+import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
@@ -152,6 +154,7 @@
import static android.system.OsConstants.IPPROTO_TCP;
import static com.android.server.ConnectivityService.DELAY_DESTROY_FROZEN_SOCKETS_VERSION;
+import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME;
import static com.android.server.ConnectivityService.KEY_DESTROY_FROZEN_SOCKETS_VERSION;
import static com.android.server.ConnectivityService.MAX_NETWORK_REQUESTS_PER_SYSTEM_UID;
import static com.android.server.ConnectivityService.PREFERENCE_ORDER_MOBILE_DATA_PREFERERRED;
@@ -250,6 +253,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ModuleInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -1903,6 +1907,7 @@
mServiceContext.setPermission(CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_GRANTED);
mServiceContext.setPermission(PACKET_KEEPALIVE_OFFLOAD, PERMISSION_GRANTED);
mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED);
+ mServiceContext.setPermission(READ_DEVICE_CONFIG, PERMISSION_GRANTED);
mAlarmManagerThread = new HandlerThread("TestAlarmManager");
mAlarmManagerThread.start();
@@ -2058,7 +2063,8 @@
@Override
public CarrierPrivilegeAuthenticator makeCarrierPrivilegeAuthenticator(
- @NonNull final Context context, @NonNull final TelephonyManager tm) {
+ @NonNull final Context context,
+ @NonNull final TelephonyManager tm) {
return mDeps.isAtLeastT() ? mCarrierPrivilegeAuthenticator : null;
}
@@ -2150,6 +2156,7 @@
public boolean isFeatureEnabled(Context context, String name) {
switch (name) {
case ConnectivityFlags.NO_REMATCH_ALL_REQUESTS_ON_REGISTER:
+ case ConnectivityFlags.CARRIER_SERVICE_CHANGED_USE_CALLBACK:
return true;
case KEY_DESTROY_FROZEN_SOCKETS_VERSION:
return true;
@@ -2404,6 +2411,7 @@
final String myPackageName = mContext.getPackageName();
final PackageInfo myPackageInfo = mContext.getPackageManager().getPackageInfo(
myPackageName, PackageManager.GET_PERMISSIONS);
+ myPackageInfo.setLongVersionCode(9_999_999L);
doReturn(new String[] {myPackageName}).when(mPackageManager)
.getPackagesForUid(Binder.getCallingUid());
doReturn(myPackageInfo).when(mPackageManager).getPackageInfoAsUser(
@@ -2415,6 +2423,13 @@
buildPackageInfo(/* SYSTEM */ false, VPN_UID)
})).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt());
+ final ModuleInfo moduleInfo = new ModuleInfo();
+ moduleInfo.setPackageName(TETHERING_MODULE_NAME);
+ doReturn(moduleInfo).when(mPackageManager)
+ .getModuleInfo(TETHERING_MODULE_NAME, PackageManager.MODULE_APEX_NAME);
+ doReturn(myPackageInfo).when(mPackageManager)
+ .getPackageInfo(TETHERING_MODULE_NAME, PackageManager.MATCH_APEX);
+
// Create a fake always-on VPN package.
final int userId = UserHandle.getCallingUserId();
final ApplicationInfo applicationInfo = new ApplicationInfo();
@@ -4871,6 +4886,34 @@
}
@Test
+ public void testNoAvoidCaptivePortalOnWearProxy() throws Exception {
+ // Bring up a BLUETOOTH network which is companion proxy on wear
+ // then set captive portal.
+ mockHasSystemFeature(PackageManager.FEATURE_WATCH, true);
+ setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID);
+ TestNetworkAgentWrapper btAgent = new TestNetworkAgentWrapper(TRANSPORT_BLUETOOTH);
+ final String firstRedirectUrl = "http://example.com/firstPath";
+
+ btAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */);
+ btAgent.assertNotDisconnected(TIMEOUT_MS);
+ }
+
+ @Test
+ public void testAvoidCaptivePortalOnBluetooth() throws Exception {
+ // When not on Wear, BLUETOOTH is just regular network,
+ // then set captive portal.
+ mockHasSystemFeature(PackageManager.FEATURE_WATCH, false);
+ setCaptivePortalMode(ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID);
+ TestNetworkAgentWrapper btAgent = new TestNetworkAgentWrapper(TRANSPORT_BLUETOOTH);
+ final String firstRedirectUrl = "http://example.com/firstPath";
+
+ btAgent.connectWithCaptivePortal(firstRedirectUrl, false /* privateDnsProbeSent */);
+
+ btAgent.expectDisconnected();
+ btAgent.expectPreventReconnectReceived();
+ }
+
+ @Test
public void testCaptivePortalApi() throws Exception {
mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED);
diff --git a/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java b/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
index 3849e49..8113626 100644
--- a/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
@@ -20,12 +20,15 @@
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
+import static com.android.server.connectivity.ConnectivityFlags.CARRIER_SERVICE_CHANGED_USE_CALLBACK;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
@@ -34,9 +37,9 @@
import static org.mockito.Mockito.verify;
import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.NetworkCapabilities;
@@ -49,14 +52,17 @@
import com.android.networkstack.apishim.TelephonyManagerShimImpl;
import com.android.networkstack.apishim.common.TelephonyManagerShim.CarrierPrivilegesListenerShim;
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
+import com.android.server.ConnectivityService;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRunner;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import org.mockito.ArgumentCaptor;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@@ -79,11 +85,13 @@
@NonNull private TestCarrierPrivilegeAuthenticator mCarrierPrivilegeAuthenticator;
private final int mCarrierConfigPkgUid = 12345;
private final String mTestPkg = "com.android.server.connectivity.test";
+ private final BroadcastReceiver mMultiSimBroadcastReceiver;
public class TestCarrierPrivilegeAuthenticator extends CarrierPrivilegeAuthenticator {
TestCarrierPrivilegeAuthenticator(@NonNull final Context c,
+ @NonNull final ConnectivityService.Dependencies deps,
@NonNull final TelephonyManager t) {
- super(c, t, mTelephonyManagerShim);
+ super(c, deps, t, mTelephonyManagerShim);
}
@Override
protected int getSlotIndex(int subId) {
@@ -92,15 +100,20 @@
}
}
- public CarrierPrivilegeAuthenticatorTest() {
+ /** Parameters to test both using callbacks or the old broadcast */
+ @Parameterized.Parameters
+ public static Collection<Boolean> shouldUseCallbacks() {
+ return Arrays.asList(true, false);
+ }
+
+ public CarrierPrivilegeAuthenticatorTest(final boolean useCallbacks) throws Exception {
mContext = mock(Context.class);
mTelephonyManager = mock(TelephonyManager.class);
mTelephonyManagerShim = mock(TelephonyManagerShimImpl.class);
mPackageManager = mock(PackageManager.class);
- }
-
- @Before
- public void setUp() throws Exception {
+ final ConnectivityService.Dependencies deps = mock(ConnectivityService.Dependencies.class);
+ doReturn(useCallbacks).when(deps).isFeatureEnabled(any() /* context */,
+ eq(CARRIER_SERVICE_CHANGED_USE_CALLBACK));
doReturn(SUBSCRIPTION_COUNT).when(mTelephonyManager).getActiveModemCount();
doReturn(mTestPkg).when(mTelephonyManagerShim)
.getCarrierServicePackageNameForLogicalSlot(anyInt());
@@ -109,13 +122,13 @@
applicationInfo.uid = mCarrierConfigPkgUid;
doReturn(applicationInfo).when(mPackageManager).getApplicationInfo(eq(mTestPkg), anyInt());
mCarrierPrivilegeAuthenticator =
- new TestCarrierPrivilegeAuthenticator(mContext, mTelephonyManager);
- }
-
- private IntentFilter getIntentFilter() {
- final ArgumentCaptor<IntentFilter> captor = ArgumentCaptor.forClass(IntentFilter.class);
- verify(mContext).registerReceiver(any(), captor.capture(), any(), any());
- return captor.getValue();
+ new TestCarrierPrivilegeAuthenticator(mContext, deps, mTelephonyManager);
+ final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext).registerReceiver(receiverCaptor.capture(), argThat(filter ->
+ filter.getAction(0).equals(ACTION_MULTI_SIM_CONFIG_CHANGED)
+ ), any() /* broadcast permissions */, any() /* handler */);
+ mMultiSimBroadcastReceiver = receiverCaptor.getValue();
}
private Map<Integer, CarrierPrivilegesListenerShim> getCarrierPrivilegesListeners() {
@@ -138,15 +151,6 @@
}
@Test
public void testConstructor() throws Exception {
- verify(mContext).registerReceiver(
- eq(mCarrierPrivilegeAuthenticator),
- any(IntentFilter.class),
- any(),
- any());
- final IntentFilter filter = getIntentFilter();
- assertEquals(1, filter.countActions());
- assertTrue(filter.hasAction(ACTION_MULTI_SIM_CONFIG_CHANGED));
-
// Two listeners originally registered, one for slot 0 and one for slot 1
final Map<Integer, CarrierPrivilegesListenerShim> initialListeners =
getCarrierPrivilegesListeners();
@@ -154,6 +158,8 @@
assertNotNull(initialListeners.get(1));
assertEquals(2, initialListeners.size());
+ initialListeners.get(0).onCarrierServiceChanged(null, mCarrierConfigPkgUid);
+
final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(0));
@@ -174,8 +180,11 @@
assertEquals(2, initialListeners.size());
doReturn(1).when(mTelephonyManager).getActiveModemCount();
- mCarrierPrivilegeAuthenticator.onReceive(
- mContext, buildTestMultiSimConfigBroadcastIntent());
+
+ // This is a little bit cavalier in that the call to onReceive is not on the handler
+ // thread that was specified in registerReceiver.
+ // TODO : capture the handler and call this on it if this causes flakiness.
+ mMultiSimBroadcastReceiver.onReceive(mContext, buildTestMultiSimConfigBroadcastIntent());
// Check all listeners have been removed
for (CarrierPrivilegesListenerShim listener : initialListeners.values()) {
verify(mTelephonyManagerShim).removeCarrierPrivilegesListener(eq(listener));
@@ -187,6 +196,8 @@
assertNotNull(newListeners.get(0));
assertEquals(1, newListeners.size());
+ newListeners.get(0).onCarrierServiceChanged(null, mCarrierConfigPkgUid);
+
final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(0);
final NetworkCapabilities nc = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
@@ -212,6 +223,7 @@
applicationInfo.uid = mCarrierConfigPkgUid + 1;
doReturn(applicationInfo).when(mPackageManager).getApplicationInfo(eq(mTestPkg), anyInt());
listener.onCarrierPrivilegesChanged(Collections.emptyList(), new int[] {});
+ listener.onCarrierServiceChanged(null, applicationInfo.uid);
assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
mCarrierConfigPkgUid, nc));
@@ -221,6 +233,9 @@
@Test
public void testDefaultSubscription() throws Exception {
+ final CarrierPrivilegesListenerShim listener = getCarrierPrivilegesListeners().get(0);
+ listener.onCarrierServiceChanged(null, mCarrierConfigPkgUid);
+
final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder();
ncBuilder.addTransportType(TRANSPORT_CELLULAR);
assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
diff --git a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
index 4158663..88044be 100644
--- a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
@@ -508,10 +508,10 @@
// Expected mtu is that the detected mtu minus MTU_DELTA(28).
assertEquals(1372, ClatCoordinator.adjustMtu(1400));
assertEquals(1472, ClatCoordinator.adjustMtu(ETHER_MTU));
- assertEquals(65508, ClatCoordinator.adjustMtu(CLAT_MAX_MTU));
+ assertEquals(1500, ClatCoordinator.adjustMtu(CLAT_MAX_MTU));
- // Expected mtu is that CLAT_MAX_MTU(65536) minus MTU_DELTA(28).
- assertEquals(65508, ClatCoordinator.adjustMtu(CLAT_MAX_MTU + 1 /* over maximum mtu */));
+ // Expected mtu is that CLAT_MAX_MTU(1528) minus MTU_DELTA(28).
+ assertEquals(1500, ClatCoordinator.adjustMtu(CLAT_MAX_MTU + 1 /* over maximum mtu */));
}
private void verifyDump(final ClatCoordinator coordinator, boolean clatStarted) {
diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt
index 5ae9232..a5a1aeb 100644
--- a/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt
+++ b/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt
@@ -131,4 +131,8 @@
}
mgr.unregisterNetworkCallback(cb)
}
+
+ fun disconnect() {
+ agent.unregister()
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
index 68613a6..b11878d 100644
--- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
+++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt
@@ -24,13 +24,16 @@
import android.net.PacProxyManager
import android.net.RouteInfo
import android.net.networkstack.NetworkStackClientBase
+import android.os.BatteryStatsManager
import android.os.Handler
import android.os.HandlerThread
import android.os.UserHandle
import android.os.UserManager
import android.telephony.TelephonyManager
import android.testing.TestableContext
+import android.util.ArraySet
import androidx.test.platform.app.InstrumentationRegistry
+import com.android.internal.app.IBatteryStats
import com.android.internal.util.test.BroadcastInterceptingContext
import com.android.modules.utils.build.SdkLevel
import com.android.networkstack.apishim.common.UnsupportedApiLevelException
@@ -41,6 +44,7 @@
import com.android.server.connectivity.MultinetworkPolicyTracker
import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies
import com.android.server.connectivity.ProxyTracker
+import com.android.testutils.visibleOnHandlerThread
import com.android.testutils.waitForIdle
import org.mockito.AdditionalAnswers.delegatesTo
import org.mockito.Mockito.doAnswer
@@ -71,7 +75,7 @@
init {
if (!SdkLevel.isAtLeastS()) {
throw UnsupportedApiLevelException("CSTest subclasses must be annotated to only " +
- "run on S+, e.g. @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)");
+ "run on S+, e.g. @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)")
}
}
@@ -112,6 +116,7 @@
val proxyTracker = ProxyTracker(context, mock<Handler>(), 16 /* EVENT_PROXY_HAS_CHANGED */)
val alarmManager = makeMockAlarmManager()
val systemConfigManager = makeMockSystemConfigManager()
+ val batteryManager = BatteryStatsManager(mock<IBatteryStats>())
val telephonyManager = mock<TelephonyManager>().also {
doReturn(true).`when`(it).isDataCapable()
}
@@ -130,8 +135,10 @@
override fun makeHandlerThread() = csHandlerThread
override fun makeProxyTracker(context: Context, connServiceHandler: Handler) = proxyTracker
- override fun makeCarrierPrivilegeAuthenticator(context: Context, tm: TelephonyManager) =
- if (SdkLevel.isAtLeastT()) mock<CarrierPrivilegeAuthenticator>() else null
+ override fun makeCarrierPrivilegeAuthenticator(
+ context: Context,
+ tm: TelephonyManager
+ ) = if (SdkLevel.isAtLeastT()) mock<CarrierPrivilegeAuthenticator>() else null
private inner class AOOKTDeps(c: Context) : AutomaticOnOffKeepaliveTracker.Dependencies(c) {
override fun isTetheringFeatureNotChickenedOut(name: String): Boolean {
@@ -150,6 +157,25 @@
// checking permissions.
override fun isFeatureEnabled(context: Context?, name: String?) =
enabledFeatures[name] ?: fail("Unmocked feature $name, see CSTest.enabledFeatures")
+
+ // Mocked change IDs
+ private val enabledChangeIds = ArraySet<Long>()
+ fun setChangeIdEnabled(enabled: Boolean, changeId: Long) {
+ // enabledChangeIds is read on the handler thread and maybe the test thread, so
+ // make sure both threads see it before continuing.
+ visibleOnHandlerThread(csHandler) {
+ if (enabled) {
+ enabledChangeIds.add(changeId)
+ } else {
+ enabledChangeIds.remove(changeId)
+ }
+ }
+ }
+
+ override fun isChangeEnabled(changeId: Long, pkg: String, user: UserHandle) =
+ changeId in enabledChangeIds
+ override fun isChangeEnabled(changeId: Long, uid: Int) =
+ changeId in enabledChangeIds
}
inner class CSContext(base: Context) : BroadcastInterceptingContext(base) {
@@ -196,6 +222,7 @@
Context.ACTIVITY_SERVICE -> activityManager
Context.SYSTEM_CONFIG_SERVICE -> systemConfigManager
Context.TELEPHONY_SERVICE -> telephonyManager
+ Context.BATTERY_STATS_SERVICE -> batteryManager
Context.STATS_MANAGER -> null // Stats manager is final and can't be mocked
else -> super.getSystemService(serviceName)
}