Merge changes Ie28e6c80,I3cb9b2ce
* changes:
ConnectivityService: dumpsys args for dumping networks or requests only.
ConnectivityService: Sort requests and networks in dumpsys.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 7be708a..ce18796 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -22,6 +22,7 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -311,6 +312,7 @@
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String INET_CONDITION_ACTION =
"android.net.conn.INET_CONDITION_ACTION";
@@ -325,6 +327,7 @@
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @UnsupportedAppUsage
public static final String ACTION_TETHER_STATE_CHANGED =
"android.net.conn.TETHER_STATE_CHANGED";
@@ -333,6 +336,7 @@
* gives a String[] listing all the interfaces configured for
* tethering and currently available for tethering.
*/
+ @UnsupportedAppUsage
public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
/**
@@ -347,6 +351,7 @@
* gives a String[] listing all the interfaces currently tethered
* (ie, has DHCPv4 support and packets potentially forwarded/NATed)
*/
+ @UnsupportedAppUsage
public static final String EXTRA_ACTIVE_TETHER = "tetherArray";
/**
@@ -355,6 +360,7 @@
* failed. Use {@link #getLastTetherError} to find the error code
* for any interfaces listed here.
*/
+ @UnsupportedAppUsage
public static final String EXTRA_ERRORED_TETHER = "erroredArray";
/**
@@ -459,6 +465,7 @@
* The absence of a connection type.
* @hide
*/
+ @UnsupportedAppUsage
public static final int TYPE_NONE = -1;
/**
@@ -575,6 +582,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static final int TYPE_MOBILE_FOTA = 10;
/**
@@ -583,6 +591,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static final int TYPE_MOBILE_IMS = 11;
/**
@@ -591,6 +600,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static final int TYPE_MOBILE_CBS = 12;
/**
@@ -600,6 +610,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static final int TYPE_WIFI_P2P = 13;
/**
@@ -608,6 +619,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static final int TYPE_MOBILE_IA = 14;
/**
@@ -617,6 +629,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static final int TYPE_MOBILE_EMERGENCY = 15;
/**
@@ -625,6 +638,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static final int TYPE_PROXY = 16;
/**
@@ -705,8 +719,9 @@
*
* @hide
*/
- public static final String PRIVATE_DNS_DEFAULT_MODE = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+ public static final String PRIVATE_DNS_DEFAULT_MODE_FALLBACK = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+ @UnsupportedAppUsage
private final IConnectivityManager mService;
/**
* A kludge to facilitate static access where a Context pointer isn't available, like in the
@@ -743,6 +758,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static String getNetworkTypeName(int type) {
switch (type) {
case TYPE_NONE:
@@ -797,6 +813,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public static boolean isNetworkTypeMobile(int networkType) {
switch (networkType) {
case TYPE_MOBILE:
@@ -1010,6 +1027,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
+ @UnsupportedAppUsage
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
return getActiveNetworkInfoForUid(uid, false);
}
@@ -1107,6 +1125,7 @@
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public Network getNetworkForType(int networkType) {
try {
return mService.getNetworkForType(networkType);
@@ -1135,6 +1154,7 @@
* the Networks that applications run by the given user will use by default.
* @hide
*/
+ @UnsupportedAppUsage
public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
try {
return mService.getDefaultNetworkCapabilitiesForUser(userId);
@@ -1153,6 +1173,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public LinkProperties getActiveLinkProperties() {
try {
return mService.getActiveLinkProperties();
@@ -1177,6 +1198,7 @@
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public LinkProperties getLinkProperties(int networkType) {
try {
return mService.getLinkPropertiesForType(networkType);
@@ -1332,6 +1354,7 @@
return 1;
}
+ @UnsupportedAppUsage
private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
if (networkType == TYPE_MOBILE) {
switch (feature) {
@@ -1495,6 +1518,7 @@
};
}
+ @UnsupportedAppUsage
private static final HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
new HashMap<>();
@@ -1523,6 +1547,7 @@
Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
}
+ @UnsupportedAppUsage
private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
int delay = -1;
int type = legacyTypeForNetworkCapabilities(netCap);
@@ -1552,6 +1577,7 @@
}
}
+ @UnsupportedAppUsage
private boolean removeRequestForFeature(NetworkCapabilities netCap) {
final LegacyRequest l;
synchronized (sLegacyRequests) {
@@ -1619,10 +1645,13 @@
/** @hide */
public static class PacketKeepaliveCallback {
/** The requested keepalive was successfully started. */
+ @UnsupportedAppUsage
public void onStarted() {}
/** The keepalive was successfully stopped. */
+ @UnsupportedAppUsage
public void onStopped() {}
/** An error occurred. */
+ @UnsupportedAppUsage
public void onError(int error) {}
}
@@ -1689,6 +1718,7 @@
mLooper.quit();
}
+ @UnsupportedAppUsage
public void stop() {
try {
mService.stopKeepalive(mNetwork, mSlot);
@@ -1744,6 +1774,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public PacketKeepalive startNattKeepalive(
Network network, int intervalSeconds, PacketKeepaliveCallback callback,
InetAddress srcAddr, int srcPort, InetAddress dstAddr) {
@@ -1805,6 +1836,7 @@
* {@link #bindProcessToNetwork} API.
*/
@Deprecated
+ @UnsupportedAppUsage
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
checkLegacyRoutingApiAccess();
try {
@@ -1848,12 +1880,14 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public void setBackgroundDataSetting(boolean allowBackgroundData) {
// ignored
}
/** {@hide} */
@Deprecated
+ @UnsupportedAppUsage
public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
try {
return mService.getActiveNetworkQuotaInfo();
@@ -1867,6 +1901,7 @@
* @deprecated Talk to TelephonyManager directly
*/
@Deprecated
+ @UnsupportedAppUsage
public boolean getMobileDataEnabled() {
IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
if (b != null) {
@@ -1986,6 +2021,7 @@
}
/** {@hide} */
+ @UnsupportedAppUsage
public static ConnectivityManager from(Context context) {
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
@@ -2036,6 +2072,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
private static ConnectivityManager getInstance() {
if (getInstanceOrNull() == null) {
throw new IllegalStateException("No ConnectivityManager yet constructed");
@@ -2052,6 +2089,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public String[] getTetherableIfaces() {
try {
return mService.getTetherableIfaces();
@@ -2068,6 +2106,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public String[] getTetheredIfaces() {
try {
return mService.getTetheredIfaces();
@@ -2090,6 +2129,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public String[] getTetheringErroredIfaces() {
try {
return mService.getTetheringErroredIfaces();
@@ -2136,6 +2176,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public int tether(String iface) {
try {
String pkgName = mContext.getOpPackageName();
@@ -2164,6 +2205,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public int untether(String iface) {
try {
String pkgName = mContext.getOpPackageName();
@@ -2317,6 +2359,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public String[] getTetherableUsbRegexs() {
try {
return mService.getTetherableUsbRegexs();
@@ -2336,6 +2379,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public String[] getTetherableWifiRegexs() {
try {
return mService.getTetherableWifiRegexs();
@@ -2355,6 +2399,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public String[] getTetherableBluetoothRegexs() {
try {
return mService.getTetherableBluetoothRegexs();
@@ -2380,6 +2425,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public int setUsbTethering(boolean enable) {
try {
String pkgName = mContext.getOpPackageName();
@@ -2426,6 +2472,7 @@
* {@hide}
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public int getLastTetherError(String iface) {
try {
return mService.getLastTetherError(iface);
@@ -2579,6 +2626,7 @@
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+ @UnsupportedAppUsage
public boolean isNetworkSupported(int networkType) {
try {
return mService.isNetworkSupported(networkType);
@@ -2680,6 +2728,7 @@
* @hide
*/
@RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
+ @UnsupportedAppUsage
public void setAirplaneMode(boolean enable) {
try {
mService.setAirplaneMode(enable);
@@ -2689,6 +2738,7 @@
}
/** {@hide} */
+ @UnsupportedAppUsage
public void registerNetworkFactory(Messenger messenger, String name) {
try {
mService.registerNetworkFactory(messenger, name);
@@ -2698,6 +2748,7 @@
}
/** {@hide} */
+ @UnsupportedAppUsage
public void unregisterNetworkFactory(Messenger messenger) {
try {
mService.unregisterNetworkFactory(messenger);
@@ -3786,9 +3837,10 @@
* @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}.
*/
@Deprecated
+ @UnsupportedAppUsage
public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
return NetworkUtils.bindProcessToNetworkForHostResolution(
- network == null ? NETID_UNSET : network.netId);
+ (network == null) ? NETID_UNSET : network.getNetIdForResolv());
}
/**
@@ -3862,4 +3914,20 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * The network watchlist is a list of domains and IP addresses that are associated with
+ * potentially harmful apps. This method returns the SHA-256 of the watchlist config file
+ * currently used by the system for validation purposes.
+ *
+ * @return Hash of network watchlist config file. Null if config does not exist.
+ */
+ public byte[] getNetworkWatchlistConfigHash() {
+ try {
+ return mService.getNetworkWatchlistConfigHash();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to get watchlist config hash");
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index a6fe738..ce95b60 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -180,4 +180,6 @@
void stopKeepalive(in Network network, int slot);
String getCaptivePortalServerUrl();
+
+ byte[] getNetworkWatchlistConfigHash();
}
diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java
index fe69f29..3319f33 100644
--- a/core/java/android/net/IpConfiguration.java
+++ b/core/java/android/net/IpConfiguration.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.net.StaticIpConfiguration;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,8 +33,9 @@
public enum IpAssignment {
/* Use statically configured IP settings. Configuration can be accessed
* with staticIpConfiguration */
+ @UnsupportedAppUsage
STATIC,
- /* Use dynamically configured IP settigns */
+ /* Use dynamically configured IP settings */
DHCP,
/* no IP details are assigned, this is used to indicate
* that any existing IP settings should be retained */
@@ -47,6 +49,7 @@
public enum ProxySettings {
/* No proxy is to be used. Any existing proxy settings
* should be cleared. */
+ @UnsupportedAppUsage
NONE,
/* Use statically configured proxy. Configuration can be accessed
* with httpProxy. */
@@ -61,6 +64,7 @@
public ProxySettings proxySettings;
+ @UnsupportedAppUsage
public ProxyInfo httpProxy;
private void init(IpAssignment ipAssignment,
@@ -79,6 +83,7 @@
init(IpAssignment.UNASSIGNED, ProxySettings.UNASSIGNED, null, null);
}
+ @UnsupportedAppUsage
public IpConfiguration(IpAssignment ipAssignment,
ProxySettings proxySettings,
StaticIpConfiguration staticIpConfiguration,
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index bcfe938..1bc0d32 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -25,6 +25,7 @@
import static android.system.OsConstants.RT_SCOPE_SITE;
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pair;
@@ -54,11 +55,13 @@
/**
* IPv4 or IPv6 address.
*/
+ @UnsupportedAppUsage
private InetAddress address;
/**
* Prefix length.
*/
+ @UnsupportedAppUsage
private int prefixLength;
/**
@@ -112,6 +115,7 @@
* @return true if the address is IPv6.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIPv6() {
return address instanceof Inet6Address;
}
@@ -163,6 +167,7 @@
* @param prefixLength The prefix length.
* @hide
*/
+ @UnsupportedAppUsage
public LinkAddress(InetAddress address, int prefixLength) {
this(address, prefixLength, 0, 0);
this.scope = scopeForUnicastAddress(address);
@@ -185,6 +190,7 @@
* @param string The string to parse.
* @hide
*/
+ @UnsupportedAppUsage
public LinkAddress(String address) {
this(address, 0, 0);
this.scope = scopeForUnicastAddress(this.address);
@@ -255,6 +261,7 @@
* otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isSameAddressAs(LinkAddress other) {
return address.equals(other.address) && prefixLength == other.prefixLength;
}
@@ -278,6 +285,7 @@
* TODO: Delete all callers and remove in favour of getPrefixLength().
* @hide
*/
+ @UnsupportedAppUsage
public int getNetworkPrefixLength() {
return getPrefixLength();
}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index bd2db92..1b9a66c 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -48,6 +49,7 @@
*/
public final class LinkProperties implements Parcelable {
// The interface described by the network link.
+ @UnsupportedAppUsage
private String mIfaceName;
private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<>();
private ArrayList<InetAddress> mDnses = new ArrayList<>();
@@ -103,9 +105,13 @@
* @hide
*/
public enum ProvisioningChange {
+ @UnsupportedAppUsage
STILL_NOT_PROVISIONED,
+ @UnsupportedAppUsage
LOST_PROVISIONING,
+ @UnsupportedAppUsage
GAINED_PROVISIONING,
+ @UnsupportedAppUsage
STILL_PROVISIONED,
}
@@ -114,6 +120,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static ProvisioningChange compareProvisioning(
LinkProperties before, LinkProperties after) {
if (before.isProvisioned() && after.isProvisioned()) {
@@ -154,12 +161,14 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public LinkProperties() {
}
/**
* @hide
*/
+ @UnsupportedAppUsage
public LinkProperties(LinkProperties source) {
if (source != null) {
mIfaceName = source.mIfaceName;
@@ -186,6 +195,7 @@
* @param iface The name of the network interface used for this link.
* @hide
*/
+ @UnsupportedAppUsage
public void setInterfaceName(String iface) {
mIfaceName = iface;
ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size());
@@ -207,6 +217,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public List<String> getAllInterfaceNames() {
List<String> interfaceNames = new ArrayList<>(mStackedLinks.size() + 1);
if (mIfaceName != null) interfaceNames.add(mIfaceName);
@@ -226,6 +237,7 @@
* @return An unmodifiable {@link List} of {@link InetAddress} for this link.
* @hide
*/
+ @UnsupportedAppUsage
public List<InetAddress> getAddresses() {
List<InetAddress> addresses = new ArrayList<>();
for (LinkAddress linkAddress : mLinkAddresses) {
@@ -238,6 +250,7 @@
* Returns all the addresses on this link and all the links stacked above it.
* @hide
*/
+ @UnsupportedAppUsage
public List<InetAddress> getAllAddresses() {
List<InetAddress> addresses = new ArrayList<>();
for (LinkAddress linkAddress : mLinkAddresses) {
@@ -265,6 +278,7 @@
* @return true if {@code address} was added or updated, false otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean addLinkAddress(LinkAddress address) {
if (address == null) {
return false;
@@ -315,6 +329,7 @@
* Returns all the addresses on this link and all the links stacked above it.
* @hide
*/
+ @UnsupportedAppUsage
public List<LinkAddress> getAllLinkAddresses() {
List<LinkAddress> addresses = new ArrayList<>(mLinkAddresses);
for (LinkProperties stacked: mStackedLinks.values()) {
@@ -331,6 +346,7 @@
* object.
* @hide
*/
+ @UnsupportedAppUsage
public void setLinkAddresses(Collection<LinkAddress> addresses) {
mLinkAddresses.clear();
for (LinkAddress address: addresses) {
@@ -345,6 +361,7 @@
* @return true if the DNS server was added, false if it was already present.
* @hide
*/
+ @UnsupportedAppUsage
public boolean addDnsServer(InetAddress dnsServer) {
if (dnsServer != null && !mDnses.contains(dnsServer)) {
mDnses.add(dnsServer);
@@ -360,6 +377,7 @@
* @return true if the DNS server was removed, false if it did not exist.
* @hide
*/
+ @UnsupportedAppUsage
public boolean removeDnsServer(InetAddress dnsServer) {
if (dnsServer != null) {
return mDnses.remove(dnsServer);
@@ -374,6 +392,7 @@
* @param dnsServers The {@link Collection} of DNS servers to set in this object.
* @hide
*/
+ @UnsupportedAppUsage
public void setDnsServers(Collection<InetAddress> dnsServers) {
mDnses.clear();
for (InetAddress dnsServer: dnsServers) {
@@ -510,6 +529,7 @@
* domains to search when resolving host names on this link.
* @hide
*/
+ @UnsupportedAppUsage
public void setDomains(String domains) {
mDomains = domains;
}
@@ -532,6 +552,7 @@
* @param mtu The MTU to use for this link.
* @hide
*/
+ @UnsupportedAppUsage
public void setMtu(int mtu) {
mMtu = mtu;
}
@@ -543,6 +564,7 @@
* @return The mtu value set for this link.
* @hide
*/
+ @UnsupportedAppUsage
public int getMtu() {
return mMtu;
}
@@ -555,6 +577,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setTcpBufferSizes(String tcpBufferSizes) {
mTcpBufferSizes = tcpBufferSizes;
}
@@ -566,6 +589,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public String getTcpBufferSizes() {
return mTcpBufferSizes;
}
@@ -589,6 +613,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public boolean addRoute(RouteInfo route) {
if (route != null) {
String routeIface = route.getInterface();
@@ -615,6 +640,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public boolean removeRoute(RouteInfo route) {
return route != null &&
Objects.equals(mIfaceName, route.getInterface()) &&
@@ -645,6 +671,7 @@
* Returns all the routes on this link and all the links stacked above it.
* @hide
*/
+ @UnsupportedAppUsage
public List<RouteInfo> getAllRoutes() {
List<RouteInfo> routes = new ArrayList<>(mRoutes);
for (LinkProperties stacked: mStackedLinks.values()) {
@@ -661,6 +688,7 @@
* @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
* @hide
*/
+ @UnsupportedAppUsage
public void setHttpProxy(ProxyInfo proxy) {
mHttpProxy = proxy;
}
@@ -685,6 +713,7 @@
* @return true if the link was stacked, false otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean addStackedLink(LinkProperties link) {
if (link != null && link.getInterfaceName() != null) {
mStackedLinks.put(link.getInterfaceName(), link);
@@ -715,6 +744,7 @@
* Returns all the links stacked on top of this link.
* @hide
*/
+ @UnsupportedAppUsage
public @NonNull List<LinkProperties> getStackedLinks() {
if (mStackedLinks.isEmpty()) {
return Collections.emptyList();
@@ -730,6 +760,7 @@
* Clears this object to its initial state.
* @hide
*/
+ @UnsupportedAppUsage
public void clear() {
mIfaceName = null;
mLinkAddresses.clear();
@@ -831,6 +862,7 @@
* @return {@code true} if there is an IPv4 address, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasIPv4Address() {
for (LinkAddress address : mLinkAddresses) {
if (address.getAddress() instanceof Inet4Address) {
@@ -858,6 +890,7 @@
* @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasGlobalIPv6Address() {
for (LinkAddress address : mLinkAddresses) {
if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) {
@@ -873,6 +906,7 @@
* @return {@code true} if there is an IPv4 default route, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasIPv4DefaultRoute() {
for (RouteInfo r : mRoutes) {
if (r.isIPv4Default()) {
@@ -888,6 +922,7 @@
* @return {@code true} if there is an IPv6 default route, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasIPv6DefaultRoute() {
for (RouteInfo r : mRoutes) {
if (r.isIPv6Default()) {
@@ -903,6 +938,7 @@
* @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasIPv4DnsServer() {
for (InetAddress ia : mDnses) {
if (ia instanceof Inet4Address) {
@@ -918,6 +954,7 @@
* @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasIPv6DnsServer() {
for (InetAddress ia : mDnses) {
if (ia instanceof Inet6Address) {
@@ -947,6 +984,7 @@
* @return {@code true} if the link is provisioned, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIPv6Provisioned() {
return (hasGlobalIPv6Address() &&
hasIPv6DefaultRoute() &&
@@ -960,6 +998,7 @@
* @return {@code true} if the link is provisioned, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isProvisioned() {
return (isIPv4Provisioned() || isIPv6Provisioned());
}
@@ -971,6 +1010,7 @@
* {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isReachable(InetAddress ip) {
final List<RouteInfo> allRoutes = getAllRoutes();
// If we don't have a route to this IP address, it's not reachable.
@@ -1008,6 +1048,7 @@
* @return {@code true} if both are identical, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIdenticalInterfaceName(LinkProperties target) {
return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
}
@@ -1019,6 +1060,7 @@
* @return {@code true} if both are identical, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIdenticalAddresses(LinkProperties target) {
Collection<InetAddress> targetAddresses = target.getAddresses();
Collection<InetAddress> sourceAddresses = getAddresses();
@@ -1033,6 +1075,7 @@
* @return {@code true} if both are identical, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIdenticalDnses(LinkProperties target) {
Collection<InetAddress> targetDnses = target.getDnsServers();
String targetDomains = target.getDomains();
@@ -1080,6 +1123,7 @@
* @return {@code true} if both are identical, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIdenticalRoutes(LinkProperties target) {
Collection<RouteInfo> targetRoutes = target.getRoutes();
return (mRoutes.size() == targetRoutes.size()) ?
@@ -1093,6 +1137,7 @@
* @return {@code true} if both are identical, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIdenticalHttpProxy(LinkProperties target) {
return getHttpProxy() == null ? target.getHttpProxy() == null :
getHttpProxy().equals(target.getHttpProxy());
@@ -1105,6 +1150,7 @@
* @return {@code true} if both are identical, {@code false} otherwise.
* @hide
*/
+ @UnsupportedAppUsage
public boolean isIdenticalStackedLinks(LinkProperties target) {
if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
return false;
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 74d6470..98f3567 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -50,6 +51,7 @@
* The MacAddress zero MAC address.
* @hide
*/
+ @UnsupportedAppUsage
public static final MacAddress ALL_ZEROS_ADDRESS = new MacAddress(0);
/** @hide */
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index d1cccac..bf2344d 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -16,11 +16,13 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.util.proto.ProtoOutputStream;
import com.android.okhttp.internalandroidapi.Dns;
import com.android.okhttp.internalandroidapi.HttpURLConnectionFactory;
@@ -58,6 +60,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public final int netId;
// Objects used to perform per-network operations such as getSocketFactory
@@ -78,6 +81,11 @@
httpKeepAlive ? Integer.parseInt(System.getProperty("http.maxConnections", "5")) : 0;
private static final long httpKeepAliveDurationMs =
Long.parseLong(System.getProperty("http.keepAliveDuration", "300000")); // 5 minutes.
+ // Value used to obfuscate network handle longs.
+ // The HANDLE_MAGIC value MUST be kept in sync with the corresponding
+ // value in the native/android/net.c NDK implementation.
+ private static final long HANDLE_MAGIC = 0xcafed00dL;
+ private static final int HANDLE_MAGIC_SIZE = 32;
// A boolean to control how getAllByName()/getByName() behaves in the face
// of Private DNS.
@@ -92,20 +100,29 @@
// anytime and (b) receivers should be explicit about attempts to bypass
// Private DNS so that the intent of the code is easily determined and
// code search audits are possible.
- private boolean mPrivateDnsBypass = false;
+ private final transient boolean mPrivateDnsBypass;
/**
* @hide
*/
+ @UnsupportedAppUsage
public Network(int netId) {
+ this(netId, false);
+ }
+
+ /**
+ * @hide
+ */
+ public Network(int netId, boolean privateDnsBypass) {
this.netId = netId;
+ this.mPrivateDnsBypass = privateDnsBypass;
}
/**
* @hide
*/
public Network(Network that) {
- this.netId = that.netId;
+ this(that.netId, that.mPrivateDnsBypass);
}
/**
@@ -124,8 +141,7 @@
* Operates the same as {@code InetAddress.getByName} except that host
* resolution is done on this network.
*
- * @param host
- * the hostName to be resolved to an address or {@code null}.
+ * @param host the hostname to be resolved to an address or {@code null}.
* @return the {@code InetAddress} instance representing the host.
* @throws UnknownHostException
* if the address lookup fails.
@@ -135,14 +151,14 @@
}
/**
- * Specify whether or not Private DNS should be bypassed when attempting
+ * Obtain a Network object for which Private DNS is to be bypassed when attempting
* to use {@link #getAllByName(String)}/{@link #getByName(String)} methods on the given
* instance for hostname resolution.
*
* @hide
*/
- public void setPrivateDnsBypass(boolean bypass) {
- mPrivateDnsBypass = bypass;
+ public Network getPrivateDnsBypassingCopy() {
+ return new Network(netId, true);
}
/**
@@ -394,6 +410,25 @@
}
/**
+ * Returns a {@link Network} object given a handle returned from {@link #getNetworkHandle}.
+ *
+ * @param networkHandle a handle returned from {@link #getNetworkHandle}.
+ * @return A {@link Network} object derived from {@code networkHandle}.
+ */
+ public static Network fromNetworkHandle(long networkHandle) {
+ if (networkHandle == 0) {
+ throw new IllegalArgumentException(
+ "Network.fromNetworkHandle refusing to instantiate NETID_UNSET Network.");
+ }
+ if ((networkHandle & ((1L << HANDLE_MAGIC_SIZE) - 1)) != HANDLE_MAGIC
+ || networkHandle < 0) {
+ throw new IllegalArgumentException(
+ "Value passed to fromNetworkHandle() is not a network handle.");
+ }
+ return new Network((int) (networkHandle >> HANDLE_MAGIC_SIZE));
+ }
+
+ /**
* Returns a handle representing this {@code Network}, for use with the NDK API.
*/
public long getNetworkHandle() {
@@ -415,14 +450,10 @@
// At some future date it may be desirable to realign the handle with
// Multiple Provisioning Domains API recommendations, as made by the
// IETF mif working group.
- //
- // The handleMagic value MUST be kept in sync with the corresponding
- // value in the native/android/net.c NDK implementation.
if (netId == 0) {
return 0L; // make this zero condition obvious for debugging
}
- final long handleMagic = 0xcafed00dL;
- return (((long) netId) << 32) | handleMagic;
+ return (((long) netId) << HANDLE_MAGIC_SIZE) | HANDLE_MAGIC;
}
// implement the Parcelable interface
@@ -462,4 +493,11 @@
public String toString() {
return Integer.toString(netId);
}
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(NetworkProto.NET_ID, netId);
+ proto.end(token);
+ }
}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 52a2354..114b423 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.net.ConnectivityManager.PacketKeepalive;
import android.os.Bundle;
@@ -351,6 +352,7 @@
/**
* Called by the bearer code when it has new NetworkInfo data.
*/
+ @UnsupportedAppUsage
public void sendNetworkInfo(NetworkInfo networkInfo) {
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
}
@@ -372,7 +374,7 @@
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
- queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
+ queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score, 0);
}
/**
@@ -387,7 +389,7 @@
* {@link #saveAcceptUnvalidated} to respect the user's choice.
*/
public void explicitlySelected(boolean acceptUnvalidated) {
- queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED, acceptUnvalidated);
+ queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED, acceptUnvalidated ? 1 : 0, 0);
}
/**
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 83553df..fd1e5f2 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -19,10 +19,12 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.net.ConnectivityManager.NetworkCallback;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.BitUtils;
@@ -55,6 +57,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public NetworkCapabilities() {
clearAll();
mNetworkCapabilities = DEFAULT_CAPABILITIES;
@@ -102,6 +105,7 @@
* Represents the network's capabilities. If any are specified they will be satisfied
* by any Network that matches all of them.
*/
+ @UnsupportedAppUsage
private long mNetworkCapabilities;
/**
@@ -264,9 +268,8 @@
/**
* Indicates that this network is not congested.
* <p>
- * When a network is congested, the device should defer network traffic that
- * can be done at a later time without breaking developer contracts.
- * @hide
+ * When a network is congested, applications should defer network traffic
+ * that can be done at a later time, such as uploading analytics.
*/
public static final int NET_CAPABILITY_NOT_CONGESTED = 20;
@@ -371,6 +374,7 @@
* @return This NetworkCapabilities instance, to facilitate chaining.
* @hide
*/
+ @UnsupportedAppUsage
public NetworkCapabilities addCapability(@NetCapability int capability) {
checkValidCapability(capability);
mNetworkCapabilities |= 1 << capability;
@@ -407,6 +411,7 @@
* @return This NetworkCapabilities instance, to facilitate chaining.
* @hide
*/
+ @UnsupportedAppUsage
public NetworkCapabilities removeCapability(@NetCapability int capability) {
checkValidCapability(capability);
final long mask = ~(1 << capability);
@@ -659,6 +664,7 @@
* @return This NetworkCapabilities instance, to facilitate chaining.
* @hide
*/
+ @UnsupportedAppUsage
public NetworkCapabilities addTransportType(@Transport int transportType) {
checkValidTransportType(transportType);
mTransportTypes |= 1 << transportType;
@@ -898,6 +904,7 @@
* specifier. See {@link #setNetworkSpecifier}.
* @hide
*/
+ @UnsupportedAppUsage
public NetworkSpecifier getNetworkSpecifier() {
return mNetworkSpecifier;
}
@@ -930,6 +937,7 @@
* Signal strength. This is a signed integer, and higher values indicate better signal.
* The exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
*/
+ @UnsupportedAppUsage
private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
/**
@@ -945,6 +953,7 @@
* @param signalStrength the bearer-specific signal strength.
* @hide
*/
+ @UnsupportedAppUsage
public NetworkCapabilities setSignalStrength(int signalStrength) {
mSignalStrength = signalStrength;
return this;
@@ -955,6 +964,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasSignalStrength() {
return mSignalStrength > SIGNAL_STRENGTH_UNSPECIFIED;
}
@@ -965,6 +975,7 @@
* @return The bearer-specific signal strength.
* @hide
*/
+ @UnsupportedAppUsage
public int getSignalStrength() {
return mSignalStrength;
}
@@ -1289,9 +1300,7 @@
// Ignore NOT_METERED being added or removed as it is effectively dynamic. http://b/63326103
// TODO: properly support NOT_METERED as a mutable and requestable capability.
- // Ignore DUN being added or removed. http://b/65257223.
- final long mask = ~MUTABLE_CAPABILITIES
- & ~(1 << NET_CAPABILITY_NOT_METERED) & ~(1 << NET_CAPABILITY_DUN);
+ final long mask = ~MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_NOT_METERED);
long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
long newImmutableCapabilities = that.mNetworkCapabilities & mask;
if (oldImmutableCapabilities != newImmutableCapabilities) {
@@ -1473,6 +1482,31 @@
}
}
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ for (int transport : getTransportTypes()) {
+ proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport);
+ }
+
+ for (int capability : getCapabilities()) {
+ proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability);
+ }
+
+ proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps);
+ proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps);
+
+ if (mNetworkSpecifier != null) {
+ proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString());
+ }
+
+ proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength());
+ proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength);
+
+ proto.end(token);
+ }
+
/**
* @hide
*/
@@ -1521,6 +1555,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public static String transportNamesOf(@Transport int[] types) {
StringJoiner joiner = new StringJoiner("|");
if (types != null) {
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 999771a..d912dd1 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -129,6 +130,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
if (!ConnectivityManager.isNetworkTypeValid(type)
&& type != ConnectivityManager.TYPE_NONE) {
@@ -143,6 +145,7 @@
}
/** {@hide} */
+ @UnsupportedAppUsage
public NetworkInfo(NetworkInfo source) {
if (source != null) {
synchronized (source) {
@@ -209,6 +212,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void setSubtype(int subtype, String subtypeName) {
synchronized (this) {
mSubtype = subtype;
@@ -317,6 +321,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public void setIsAvailable(boolean isAvailable) {
synchronized (this) {
mIsAvailable = isAvailable;
@@ -347,6 +352,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public void setFailover(boolean isFailover) {
synchronized (this) {
mIsFailover = isFailover;
@@ -377,6 +383,7 @@
*/
@VisibleForTesting
@Deprecated
+ @UnsupportedAppUsage
public void setRoaming(boolean isRoaming) {
synchronized (this) {
mIsRoaming = isRoaming;
@@ -422,6 +429,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
synchronized (this) {
this.mDetailedState = detailedState;
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index f3669fb..04b6b44 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -17,12 +17,14 @@
package android.net;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.net.NetworkCapabilities.NetCapability;
import android.net.NetworkCapabilities.Transport;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
import android.text.TextUtils;
+import android.util.proto.ProtoOutputStream;
import java.util.Objects;
import java.util.Set;
@@ -37,6 +39,7 @@
* The {@link NetworkCapabilities} that define this request.
* @hide
*/
+ @UnsupportedAppUsage
public final @NonNull NetworkCapabilities networkCapabilities;
/**
@@ -45,6 +48,7 @@
* the request.
* @hide
*/
+ @UnsupportedAppUsage
public final int requestId;
/**
@@ -52,6 +56,7 @@
* Causes CONNECTIVITY_ACTION broadcasts to be sent.
* @hide
*/
+ @UnsupportedAppUsage
public final int legacyType;
/**
@@ -240,6 +245,7 @@
* @return The builder to facilitate chaining.
* @hide
*/
+ @UnsupportedAppUsage
public Builder clearCapabilities() {
mNetworkCapabilities.clearAll();
return this;
@@ -338,6 +344,7 @@
* @param signalStrength the bearer-specific signal strength.
* @hide
*/
+ @UnsupportedAppUsage
public Builder setSignalStrength(int signalStrength) {
mNetworkCapabilities.setSignalStrength(signalStrength);
return this;
@@ -453,6 +460,35 @@
", " + networkCapabilities.toString() + " ]";
}
+ private int typeToProtoEnum(Type t) {
+ switch (t) {
+ case NONE:
+ return NetworkRequestProto.TYPE_NONE;
+ case LISTEN:
+ return NetworkRequestProto.TYPE_LISTEN;
+ case TRACK_DEFAULT:
+ return NetworkRequestProto.TYPE_TRACK_DEFAULT;
+ case REQUEST:
+ return NetworkRequestProto.TYPE_REQUEST;
+ case BACKGROUND_REQUEST:
+ return NetworkRequestProto.TYPE_BACKGROUND_REQUEST;
+ default:
+ return NetworkRequestProto.TYPE_UNKNOWN;
+ }
+ }
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
+ proto.write(NetworkRequestProto.REQUEST_ID, requestId);
+ proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
+ networkCapabilities.writeToProto(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
+
+ proto.end(token);
+ }
+
public boolean equals(Object obj) {
if (obj instanceof NetworkRequest == false) return false;
NetworkRequest that = (NetworkRequest)obj;
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index b00cb48..c545ee2 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Slog;
@@ -26,11 +27,14 @@
* @hide
*/
public class NetworkState implements Parcelable {
+ private static final boolean SANITY_CHECK_ROAMING = false;
+
public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null);
public final NetworkInfo networkInfo;
public final LinkProperties linkProperties;
public final NetworkCapabilities networkCapabilities;
+ @UnsupportedAppUsage
public final Network network;
public final String subscriberId;
public final String networkId;
@@ -47,7 +51,7 @@
// This object is an atomic view of a network, so the various components
// should always agree on roaming state.
- if (networkInfo != null && networkCapabilities != null) {
+ if (SANITY_CHECK_ROAMING && networkInfo != null && networkCapabilities != null) {
if (networkInfo.isRoaming() == networkCapabilities
.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
@@ -56,6 +60,7 @@
}
}
+ @UnsupportedAppUsage
public NetworkState(Parcel in) {
networkInfo = in.readParcelable(null);
linkProperties = in.readParcelable(null);
@@ -80,6 +85,7 @@
out.writeString(networkId);
}
+ @UnsupportedAppUsage
public static final Creator<NetworkState> CREATOR = new Creator<NetworkState>() {
@Override
public NetworkState createFromParcel(Parcel in) {
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 9a5d502..34e9476 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -16,11 +16,13 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.util.Log;
import android.util.Pair;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
@@ -43,6 +45,7 @@
/**
* Attaches a socket filter that accepts DHCP packets to the given socket.
*/
+ @UnsupportedAppUsage
public native static void attachDhcpFilter(FileDescriptor fd) throws SocketException;
/**
@@ -50,6 +53,7 @@
* @param fd the socket's {@link FileDescriptor}.
* @param packetType the hardware address type, one of ARPHRD_*.
*/
+ @UnsupportedAppUsage
public native static void attachRaFilter(FileDescriptor fd, int packetType) throws SocketException;
/**
@@ -60,6 +64,7 @@
* @param fd the socket's {@link FileDescriptor}.
* @param packetType the hardware address type, one of ARPHRD_*.
*/
+ @UnsupportedAppUsage
public native static void attachControlPacketFilter(FileDescriptor fd, int packetType)
throws SocketException;
@@ -108,6 +113,7 @@
* this socket will go directly to the underlying network, so its traffic will not be
* forwarded through the VPN.
*/
+ @UnsupportedAppUsage
public static boolean protectFromVpn(FileDescriptor fd) {
return protectFromVpn(fd.getInt$());
}
@@ -126,51 +132,135 @@
public native static boolean queryUserAccess(int uid, int netId);
/**
- * Convert a IPv4 address from an integer to an InetAddress.
- * @param hostAddress an int corresponding to the IPv4 address in network byte order
+ * Add an entry into the ARP cache.
*/
+ public static void addArpEntry(Inet4Address ipv4Addr, MacAddress ethAddr, String ifname,
+ FileDescriptor fd) throws IOException {
+ addArpEntry(ethAddr.toByteArray(), ipv4Addr.getAddress(), ifname, fd);
+ }
+
+ private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
+ FileDescriptor fd) throws IOException;
+
+ /**
+ * @see #intToInet4AddressHTL(int)
+ * @deprecated Use either {@link #intToInet4AddressHTH(int)}
+ * or {@link #intToInet4AddressHTL(int)}
+ */
+ @Deprecated
+ @UnsupportedAppUsage
public static InetAddress intToInetAddress(int hostAddress) {
- byte[] addressBytes = { (byte)(0xff & hostAddress),
- (byte)(0xff & (hostAddress >> 8)),
- (byte)(0xff & (hostAddress >> 16)),
- (byte)(0xff & (hostAddress >> 24)) };
+ return intToInet4AddressHTL(hostAddress);
+ }
+
+ /**
+ * Convert a IPv4 address from an integer to an InetAddress (0x04030201 -> 1.2.3.4)
+ *
+ * <p>This method uses the higher-order int bytes as the lower-order IPv4 address bytes,
+ * which is an unusual convention. Consider {@link #intToInet4AddressHTH(int)} instead.
+ * @param hostAddress an int coding for an IPv4 address, where higher-order int byte is
+ * lower-order IPv4 address byte
+ */
+ public static Inet4Address intToInet4AddressHTL(int hostAddress) {
+ return intToInet4AddressHTH(Integer.reverseBytes(hostAddress));
+ }
+
+ /**
+ * Convert a IPv4 address from an integer to an InetAddress (0x01020304 -> 1.2.3.4)
+ * @param hostAddress an int coding for an IPv4 address
+ */
+ public static Inet4Address intToInet4AddressHTH(int hostAddress) {
+ byte[] addressBytes = { (byte) (0xff & (hostAddress >> 24)),
+ (byte) (0xff & (hostAddress >> 16)),
+ (byte) (0xff & (hostAddress >> 8)),
+ (byte) (0xff & hostAddress) };
try {
- return InetAddress.getByAddress(addressBytes);
+ return (Inet4Address) InetAddress.getByAddress(addressBytes);
} catch (UnknownHostException e) {
- throw new AssertionError();
+ throw new AssertionError();
}
}
/**
- * Convert a IPv4 address from an InetAddress to an integer
- * @param inetAddr is an InetAddress corresponding to the IPv4 address
- * @return the IP address as an integer in network byte order
+ * @see #inet4AddressToIntHTL(Inet4Address)
+ * @deprecated Use either {@link #inet4AddressToIntHTH(Inet4Address)}
+ * or {@link #inet4AddressToIntHTL(Inet4Address)}
*/
+ @Deprecated
public static int inetAddressToInt(Inet4Address inetAddr)
throws IllegalArgumentException {
- byte [] addr = inetAddr.getAddress();
- return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
- ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
+ return inet4AddressToIntHTL(inetAddr);
}
/**
- * Convert a network prefix length to an IPv4 netmask integer
- * @param prefixLength
- * @return the IPv4 netmask as an integer in network byte order
+ * Convert an IPv4 address from an InetAddress to an integer (1.2.3.4 -> 0x01020304)
+ *
+ * <p>This conversion can help order IP addresses: considering the ordering
+ * 192.0.2.1 < 192.0.2.2 < ..., resulting ints will follow that ordering if read as unsigned
+ * integers with {@link Integer#toUnsignedLong}.
+ * @param inetAddr is an InetAddress corresponding to the IPv4 address
+ * @return the IP address as integer
*/
+ public static int inet4AddressToIntHTH(Inet4Address inetAddr)
+ throws IllegalArgumentException {
+ byte [] addr = inetAddr.getAddress();
+ return ((addr[0] & 0xff) << 24) | ((addr[1] & 0xff) << 16)
+ | ((addr[2] & 0xff) << 8) | (addr[3] & 0xff);
+ }
+
+ /**
+ * Convert a IPv4 address from an InetAddress to an integer (1.2.3.4 -> 0x04030201)
+ *
+ * <p>This method stores the higher-order IPv4 address bytes in the lower-order int bytes,
+ * which is an unusual convention. Consider {@link #inet4AddressToIntHTH(Inet4Address)} instead.
+ * @param inetAddr is an InetAddress corresponding to the IPv4 address
+ * @return the IP address as integer
+ */
+ public static int inet4AddressToIntHTL(Inet4Address inetAddr) {
+ return Integer.reverseBytes(inet4AddressToIntHTH(inetAddr));
+ }
+
+ /**
+ * @see #prefixLengthToV4NetmaskIntHTL(int)
+ * @deprecated Use either {@link #prefixLengthToV4NetmaskIntHTH(int)}
+ * or {@link #prefixLengthToV4NetmaskIntHTL(int)}
+ */
+ @Deprecated
+ @UnsupportedAppUsage
public static int prefixLengthToNetmaskInt(int prefixLength)
throws IllegalArgumentException {
+ return prefixLengthToV4NetmaskIntHTL(prefixLength);
+ }
+
+ /**
+ * Convert a network prefix length to an IPv4 netmask integer (prefixLength 17 -> 0xffff8000)
+ * @return the IPv4 netmask as an integer
+ */
+ public static int prefixLengthToV4NetmaskIntHTH(int prefixLength)
+ throws IllegalArgumentException {
if (prefixLength < 0 || prefixLength > 32) {
throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
}
- int value = 0xffffffff << (32 - prefixLength);
- return Integer.reverseBytes(value);
+ // (int)a << b is equivalent to a << (b & 0x1f): can't shift by 32 (-1 << 32 == -1)
+ return prefixLength == 0 ? 0 : 0xffffffff << (32 - prefixLength);
+ }
+
+ /**
+ * Convert a network prefix length to an IPv4 netmask integer (prefixLength 17 -> 0x0080ffff).
+ *
+ * <p>This method stores the higher-order IPv4 address bytes in the lower-order int bytes,
+ * which is an unusual convention. Consider {@link #prefixLengthToV4NetmaskIntHTH(int)} instead.
+ * @return the IPv4 netmask as an integer
+ */
+ public static int prefixLengthToV4NetmaskIntHTL(int prefixLength)
+ throws IllegalArgumentException {
+ return Integer.reverseBytes(prefixLengthToV4NetmaskIntHTH(prefixLength));
}
/**
* Convert a IPv4 netmask integer to a prefix length
- * @param netmask as an integer in network byte order
+ * @param netmask as an integer (0xff000000 for a /8 subnet)
* @return the network prefix length
*/
public static int netmaskIntToPrefixLength(int netmask) {
@@ -184,6 +274,7 @@
* @throws IllegalArgumentException the specified netmask was not contiguous.
* @hide
*/
+ @UnsupportedAppUsage
public static int netmaskToPrefixLength(Inet4Address netmask) {
// inetAddressToInt returns an int in *network* byte order.
int i = Integer.reverseBytes(inetAddressToInt(netmask));
@@ -204,6 +295,7 @@
* @return the InetAddress
* @hide
*/
+ @UnsupportedAppUsage
public static InetAddress numericToInetAddress(String addrString)
throws IllegalArgumentException {
return InetAddress.parseNumericAddress(addrString);
@@ -278,6 +370,7 @@
/**
* Returns the implicit netmask of an IPv4 address, as was the custom before 1993.
*/
+ @UnsupportedAppUsage
public static int getImplicitNetmask(Inet4Address address) {
int firstByte = address.getAddress()[0] & 0xff; // Convert to an unsigned value.
if (firstByte < 128) {
@@ -316,6 +409,28 @@
}
/**
+ * Get a prefix mask as Inet4Address for a given prefix length.
+ *
+ * <p>For example 20 -> 255.255.240.0
+ */
+ public static Inet4Address getPrefixMaskAsInet4Address(int prefixLength)
+ throws IllegalArgumentException {
+ return intToInet4AddressHTH(prefixLengthToV4NetmaskIntHTH(prefixLength));
+ }
+
+ /**
+ * Get the broadcast address for a given prefix.
+ *
+ * <p>For example 192.168.0.1/24 -> 192.168.0.255
+ */
+ public static Inet4Address getBroadcastAddress(Inet4Address addr, int prefixLength)
+ throws IllegalArgumentException {
+ final int intBroadcastAddr = inet4AddressToIntHTH(addr)
+ | ~prefixLengthToV4NetmaskIntHTH(prefixLength);
+ return intToInet4AddressHTH(intBroadcastAddr);
+ }
+
+ /**
* Check if IP address type is consistent between two InetAddress.
* @return true if both are the same type. False otherwise.
*/
@@ -368,6 +483,7 @@
* @param addr a string representing an ip addr
* @return a string propertly trimmed
*/
+ @UnsupportedAppUsage
public static String trimV4AddrZeros(String addr) {
if (addr == null) return null;
String[] octets = addr.split("\\.");
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index 5f5e623..e926fda 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -17,6 +17,7 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -91,6 +92,7 @@
* Create a ProxyProperties that points at a HTTP Proxy.
* @hide
*/
+ @UnsupportedAppUsage
public ProxyInfo(String host, int port, String exclList) {
mHost = host;
mPort = port;
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 90a2460..3e73d3d 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -55,6 +56,7 @@
/**
* The gateway address for this route.
*/
+ @UnsupportedAppUsage
private final InetAddress mGateway;
/**
@@ -79,6 +81,7 @@
// Derived data members.
// TODO: remove these.
+ @UnsupportedAppUsage
private final boolean mIsHost;
private final boolean mHasGateway;
@@ -160,6 +163,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
this(destination, gateway, iface, RTN_UNICAST);
}
@@ -167,6 +171,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
this(destination == null ? null :
new IpPrefix(destination.getAddress(), destination.getPrefixLength()),
@@ -197,6 +202,7 @@
*
* TODO: Remove this.
*/
+ @UnsupportedAppUsage
public RouteInfo(LinkAddress destination, InetAddress gateway) {
this(destination, gateway, null);
}
@@ -208,6 +214,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public RouteInfo(InetAddress gateway) {
this((IpPrefix) null, gateway, null);
}
@@ -258,6 +265,7 @@
}
}
+ @UnsupportedAppUsage
private boolean isHost() {
return (mDestination.getAddress() instanceof Inet4Address &&
mDestination.getPrefixLength() == 32) ||
@@ -355,6 +363,7 @@
* @return {@code true} if a gateway is specified
* @hide
*/
+ @UnsupportedAppUsage
public boolean hasGateway() {
return mHasGateway;
}
@@ -379,6 +388,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
if ((routes == null) || (dest == null)) return null;
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 58b1b88..3aa56b9 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.UnsupportedAppUsage;
import android.net.LinkAddress;
import android.os.Parcelable;
import android.os.Parcel;
@@ -46,11 +47,16 @@
* @hide
*/
public class StaticIpConfiguration implements Parcelable {
+ @UnsupportedAppUsage
public LinkAddress ipAddress;
+ @UnsupportedAppUsage
public InetAddress gateway;
+ @UnsupportedAppUsage
public final ArrayList<InetAddress> dnsServers;
+ @UnsupportedAppUsage
public String domains;
+ @UnsupportedAppUsage
public StaticIpConfiguration() {
dnsServers = new ArrayList<InetAddress>();
}
@@ -80,6 +86,7 @@
* route to the gateway as well. This configuration is arguably invalid, but it used to work
* in K and earlier, and other OSes appear to accept it.
*/
+ @UnsupportedAppUsage
public List<RouteInfo> getRoutes(String iface) {
List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
if (ipAddress != null) {
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 823f1cc..9b138eb 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -323,6 +323,55 @@
return (jboolean) !queryUserAccess(uid, netId);
}
+static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst)
+{
+ if (env->GetArrayLength(addr) != len) {
+ return false;
+ }
+ env->GetByteArrayRegion(addr, 0, len, reinterpret_cast<jbyte*>(dst));
+ return true;
+}
+
+static void android_net_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
+ jbyteArray ipv4Addr, jstring ifname, jobject javaFd)
+{
+ struct arpreq req = {};
+ struct sockaddr_in& netAddrStruct = *reinterpret_cast<sockaddr_in*>(&req.arp_pa);
+ struct sockaddr& ethAddrStruct = req.arp_ha;
+
+ ethAddrStruct.sa_family = ARPHRD_ETHER;
+ if (!checkLenAndCopy(env, ethAddr, ETH_ALEN, ethAddrStruct.sa_data)) {
+ jniThrowException(env, "java/io/IOException", "Invalid ethAddr length");
+ return;
+ }
+
+ netAddrStruct.sin_family = AF_INET;
+ if (!checkLenAndCopy(env, ipv4Addr, sizeof(in_addr), &netAddrStruct.sin_addr)) {
+ jniThrowException(env, "java/io/IOException", "Invalid ipv4Addr length");
+ return;
+ }
+
+ int ifLen = env->GetStringLength(ifname);
+ // IFNAMSIZ includes the terminating NULL character
+ if (ifLen >= IFNAMSIZ) {
+ jniThrowException(env, "java/io/IOException", "ifname too long");
+ return;
+ }
+ env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);
+
+ req.arp_flags = ATF_COM; // Completed entry (ha valid)
+ int fd = jniGetFDFromFileDescriptor(env, javaFd);
+ if (fd < 0) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
+ return;
+ }
+ // See also: man 7 arp
+ if (ioctl(fd, SIOCSARP, &req)) {
+ jniThrowExceptionFmt(env, "java/io/IOException", "ioctl error: %s", strerror(errno));
+ return;
+ }
+}
+
// ----------------------------------------------------------------------------
@@ -337,6 +386,7 @@
{ "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
{ "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
{ "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
+ { "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) android_net_utils_addArpEntry },
{ "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
{ "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachRaFilter },
{ "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) android_net_utils_attachControlPacketFilter },
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index dec1c1f..7602090 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -74,6 +74,7 @@
import android.net.NetworkSpecifier;
import android.net.NetworkState;
import android.net.NetworkUtils;
+import android.net.NetworkWatchlistManager;
import android.net.Proxy;
import android.net.ProxyInfo;
import android.net.RouteInfo;
@@ -146,6 +147,7 @@
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
+import com.android.server.connectivity.MultipathPolicyTracker;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.NetworkMonitor;
@@ -161,6 +163,7 @@
import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.utils.PriorityDump;
import com.google.android.collect.Lists;
@@ -500,9 +503,15 @@
private final IpConnectivityLog mMetricsLog;
+ @GuardedBy("mBandwidthRequests")
+ private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10);
+
@VisibleForTesting
final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
+ @VisibleForTesting
+ final MultipathPolicyTracker mMultipathPolicyTracker;
+
/**
* Implements support for the legacy "one network per network type" model.
*
@@ -692,6 +701,28 @@
}
private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
+ /**
+ * Helper class which parses out priority arguments and dumps sections according to their
+ * priority. If priority arguments are omitted, function calls the legacy dump command.
+ */
+ private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
+ @Override
+ public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
+ doDump(fd, pw, new String[] {DIAG_ARG}, asProto);
+ doDump(fd, pw, new String[] {SHORT_ARG}, asProto);
+ }
+
+ @Override
+ public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
+ doDump(fd, pw, args, asProto);
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
+ doDump(fd, pw, args, asProto);
+ }
+ };
+
public ConnectivityService(Context context, INetworkManagementService netManager,
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
this(context, netManager, statsService, policyManager, new IpConnectivityLog());
@@ -860,6 +891,8 @@
mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
mMultinetworkPolicyTracker.start();
+ mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
+
mDnsManager = new DnsManager(mContext, mNetd, mSystemProperties);
registerPrivateDnsSettingsCallbacks();
}
@@ -1965,8 +1998,13 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ PriorityDump.dump(mPriorityDumper, fd, writer, args);
+ }
+
+ private void doDump(FileDescriptor fd, PrintWriter writer, String[] args, boolean asProto) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+ if (asProto) return;
if (ArrayUtils.contains(args, DIAG_ARG)) {
dumpNetworkDiagnostics(pw);
@@ -2021,6 +2059,9 @@
pw.println();
dumpAvoidBadWifiSettings(pw);
+ pw.println();
+ mMultipathPolicyTracker.dump(pw);
+
if (ArrayUtils.contains(args, SHORT_ARG) == false) {
pw.println();
synchronized (mValidationLogs) {
@@ -2057,6 +2098,18 @@
pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
}
mWakelockLogs.reverseDump(fd, pw, args);
+
+ pw.println();
+ pw.println("bandwidth update requests (by uid):");
+ pw.increaseIndent();
+ synchronized (mBandwidthRequests) {
+ for (int i = 0; i < mBandwidthRequests.size(); i++) {
+ pw.println("[" + mBandwidthRequests.keyAt(i)
+ + "]: " + mBandwidthRequests.valueAt(i));
+ }
+ }
+ pw.decreaseIndent();
+
pw.decreaseIndent();
}
}
@@ -2178,8 +2231,7 @@
break;
}
case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
- Integer score = (Integer) msg.obj;
- if (score != null) updateNetworkScore(nai, score.intValue());
+ updateNetworkScore(nai, msg.arg1);
break;
}
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
@@ -2187,7 +2239,7 @@
loge("ERROR: already-connected network explicitly selected.");
}
nai.networkMisc.explicitlySelected = true;
- nai.networkMisc.acceptUnvalidated = (boolean) msg.obj;
+ nai.networkMisc.acceptUnvalidated = msg.arg1 == 1;
break;
}
case NetworkAgent.EVENT_PACKET_KEEPALIVE: {
@@ -2969,6 +3021,11 @@
return ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
}
+ Integer networkPreference = mMultipathPolicyTracker.getMultipathPreference(network);
+ if (networkPreference != null) {
+ return networkPreference;
+ }
+
return mMultinetworkPolicyTracker.getMeteredMultipathPreference();
}
@@ -3062,6 +3119,7 @@
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
nai.networkMonitor.systemReady = true;
}
+ mMultipathPolicyTracker.start();
break;
}
case EVENT_REVALIDATE_NETWORK: {
@@ -4260,6 +4318,14 @@
}
if (nai != null) {
nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE);
+ synchronized (mBandwidthRequests) {
+ final int uid = Binder.getCallingUid();
+ Integer uidReqs = mBandwidthRequests.get(uid);
+ if (uidReqs == null) {
+ uidReqs = new Integer(0);
+ }
+ mBandwidthRequests.put(uid, ++uidReqs);
+ }
return true;
}
return false;
@@ -4716,7 +4782,12 @@
*/
private NetworkCapabilities mixInCapabilities(NetworkAgentInfo nai, NetworkCapabilities nc) {
// Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
+ // Don't complain for VPNs since they're not driven by requests and there is no risk of
+ // causing a connect/teardown loop.
+ // TODO: remove this altogether and make it the responsibility of the NetworkFactories to
+ // avoid connect/teardown loops.
if (nai.everConnected &&
+ !nai.isVPN() &&
!nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
// TODO: consider not complaining when a network agent degrades its capabilities if this
// does not cause any request (that is not a listen) currently matching that agent to
@@ -5744,6 +5815,17 @@
Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
}
+ @Override
+ public byte[] getNetworkWatchlistConfigHash() {
+ NetworkWatchlistManager nwm = mContext.getSystemService(NetworkWatchlistManager.class);
+ if (nwm == null) {
+ loge("Unable to get NetworkWatchlistManager");
+ return null;
+ }
+ // Redirect it to network watchlist service to access watchlist file and calculate hash.
+ return nwm.getWatchlistConfigHash();
+ }
+
@VisibleForTesting
public NetworkMonitor createNetworkMonitor(Context context, Handler handler,
NetworkAgentInfo nai, NetworkRequest defaultRequest) {
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index d51a196..b8f057d 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -16,7 +16,7 @@
package com.android.server.connectivity;
-import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
@@ -24,6 +24,7 @@
import static android.provider.Settings.Global.DNS_RESOLVER_MAX_SAMPLES;
import static android.provider.Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS;
import static android.provider.Settings.Global.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT;
+import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
@@ -34,7 +35,6 @@
import android.net.Network;
import android.net.NetworkUtils;
import android.net.Uri;
-import android.net.dns.ResolvUtil;
import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.UserHandle;
@@ -173,17 +173,9 @@
return new PrivateDnsConfig(useTls);
}
- public static PrivateDnsConfig tryBlockingResolveOf(Network network, String name) {
- try {
- final InetAddress[] ips = ResolvUtil.blockingResolveAllLocally(network, name);
- return new PrivateDnsConfig(name, ips);
- } catch (UnknownHostException uhe) {
- return new PrivateDnsConfig(name, null);
- }
- }
-
public static Uri[] getPrivateDnsSettingsUris() {
return new Uri[]{
+ Settings.Global.getUriFor(PRIVATE_DNS_DEFAULT_MODE),
Settings.Global.getUriFor(PRIVATE_DNS_MODE),
Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER),
};
@@ -485,8 +477,10 @@
}
private static String getPrivateDnsMode(ContentResolver cr) {
- final String mode = getStringSetting(cr, PRIVATE_DNS_MODE);
- return !TextUtils.isEmpty(mode) ? mode : PRIVATE_DNS_DEFAULT_MODE;
+ String mode = getStringSetting(cr, PRIVATE_DNS_MODE);
+ if (TextUtils.isEmpty(mode)) mode = getStringSetting(cr, PRIVATE_DNS_DEFAULT_MODE);
+ if (TextUtils.isEmpty(mode)) mode = PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
+ return mode;
}
private static String getStringSetting(ContentResolver cr, String which) {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index d578e95..7b8571c 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -24,6 +24,7 @@
import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
+import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -34,6 +35,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.net.Uri;
+import android.os.Build;
import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -155,9 +157,8 @@
}
@VisibleForTesting
- boolean isPreinstalledSystemApp(PackageInfo app) {
- int flags = app.applicationInfo != null ? app.applicationInfo.flags : 0;
- return (flags & (FLAG_SYSTEM | FLAG_UPDATED_SYSTEM_APP)) != 0;
+ static boolean isVendorApp(@NonNull ApplicationInfo appInfo) {
+ return appInfo.isVendor() || appInfo.isOem() || appInfo.isProduct();
}
@VisibleForTesting
@@ -177,7 +178,13 @@
}
private boolean hasRestrictedNetworkPermission(PackageInfo app) {
- if (isPreinstalledSystemApp(app)) return true;
+ // TODO : remove this check in the future(b/31479477). All apps should just
+ // request the appropriate permission for their use case since android Q.
+ if (app.applicationInfo != null
+ && app.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q
+ && isVendorApp(app.applicationInfo)) {
+ return true;
+ }
return hasPermission(app, CONNECTIVITY_INTERNAL)
|| hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
}
@@ -186,13 +193,8 @@
// This function defines what it means to hold the permission to use
// background networks.
return hasPermission(app, CHANGE_NETWORK_STATE)
- || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS)
- || hasPermission(app, CONNECTIVITY_INTERNAL)
|| hasPermission(app, NETWORK_STACK)
- // TODO : remove this check (b/31479477). Not all preinstalled apps should
- // have access to background networks, they should just request the appropriate
- // permission for their use case from the list above.
- || isPreinstalledSystemApp(app);
+ || hasRestrictedNetworkPermission(app);
}
public boolean hasUseBackgroundNetworksPermission(int uid) {
@@ -202,7 +204,9 @@
// Only using the first package name. There may be multiple names if multiple
// apps share the same UID, but in that case they also share permissions so
// querying with any of the names will return the same results.
- final PackageInfo app = mPackageManager.getPackageInfo(names[0], GET_PERMISSIONS);
+ int userId = UserHandle.getUserId(uid);
+ final PackageInfo app = mPackageManager.getPackageInfoAsUser(
+ names[0], GET_PERMISSIONS, userId);
return hasUseBackgroundNetworksPermission(app);
} catch (NameNotFoundException e) {
// App not found.
diff --git a/services/net/java/android/net/util/MultinetworkPolicyTracker.java b/services/net/java/android/net/util/MultinetworkPolicyTracker.java
index 424e40d..30c5cd9 100644
--- a/services/net/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/services/net/java/android/net/util/MultinetworkPolicyTracker.java
@@ -122,6 +122,7 @@
return mAvoidBadWifi;
}
+ // TODO: move this to MultipathPolicyTracker.
public int getMeteredMultipathPreference() {
return mMeteredMultipathPreference;
}
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index 2f4d69e..b40921f 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -19,7 +19,6 @@
import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
@@ -159,14 +158,6 @@
assertEquals("", nc1.describeImmutableDifferences(nc2));
assertEquals("", nc1.describeImmutableDifferences(nc1));
- // DUN changing (http://b/65257223)
- nc1 = new NetworkCapabilities()
- .addCapability(NET_CAPABILITY_DUN)
- .addCapability(NET_CAPABILITY_INTERNET);
- nc2 = new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET);
- assertEquals("", nc1.describeImmutableDifferences(nc2));
- assertEquals("", nc1.describeImmutableDifferences(nc1));
-
// Immutable capability changing
nc1 = new NetworkCapabilities()
.addCapability(NET_CAPABILITY_INTERNET)
diff --git a/tests/net/java/android/net/NetworkUtilsTest.java b/tests/net/java/android/net/NetworkUtilsTest.java
index a5ee8e3..3452819 100644
--- a/tests/net/java/android/net/NetworkUtilsTest.java
+++ b/tests/net/java/android/net/NetworkUtilsTest.java
@@ -16,17 +16,34 @@
package android.net;
-import android.net.NetworkUtils;
-import android.test.suitebuilder.annotation.SmallTest;
+import static android.net.NetworkUtils.getImplicitNetmask;
+import static android.net.NetworkUtils.inet4AddressToIntHTH;
+import static android.net.NetworkUtils.inet4AddressToIntHTL;
+import static android.net.NetworkUtils.intToInet4AddressHTH;
+import static android.net.NetworkUtils.intToInet4AddressHTL;
+import static android.net.NetworkUtils.netmaskToPrefixLength;
+import static android.net.NetworkUtils.prefixLengthToV4NetmaskIntHTH;
+import static android.net.NetworkUtils.prefixLengthToV4NetmaskIntHTL;
+import static android.net.NetworkUtils.getBroadcastAddress;
+import static android.net.NetworkUtils.getPrefixMaskAsInet4Address;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.junit.Assert.fail;
+
+import android.support.test.runner.AndroidJUnit4;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.TreeSet;
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class NetworkUtilsTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@android.support.test.filters.SmallTest
+public class NetworkUtilsTest {
private InetAddress Address(String addr) {
return InetAddress.parseNumericAddress(addr);
@@ -36,41 +53,125 @@
return (Inet4Address) Address(addr);
}
- @SmallTest
+ @Test
public void testGetImplicitNetmask() {
- assertEquals(8, NetworkUtils.getImplicitNetmask(IPv4Address("4.2.2.2")));
- assertEquals(8, NetworkUtils.getImplicitNetmask(IPv4Address("10.5.6.7")));
- assertEquals(16, NetworkUtils.getImplicitNetmask(IPv4Address("173.194.72.105")));
- assertEquals(16, NetworkUtils.getImplicitNetmask(IPv4Address("172.23.68.145")));
- assertEquals(24, NetworkUtils.getImplicitNetmask(IPv4Address("192.0.2.1")));
- assertEquals(24, NetworkUtils.getImplicitNetmask(IPv4Address("192.168.5.1")));
- assertEquals(32, NetworkUtils.getImplicitNetmask(IPv4Address("224.0.0.1")));
- assertEquals(32, NetworkUtils.getImplicitNetmask(IPv4Address("255.6.7.8")));
+ assertEquals(8, getImplicitNetmask(IPv4Address("4.2.2.2")));
+ assertEquals(8, getImplicitNetmask(IPv4Address("10.5.6.7")));
+ assertEquals(16, getImplicitNetmask(IPv4Address("173.194.72.105")));
+ assertEquals(16, getImplicitNetmask(IPv4Address("172.23.68.145")));
+ assertEquals(24, getImplicitNetmask(IPv4Address("192.0.2.1")));
+ assertEquals(24, getImplicitNetmask(IPv4Address("192.168.5.1")));
+ assertEquals(32, getImplicitNetmask(IPv4Address("224.0.0.1")));
+ assertEquals(32, getImplicitNetmask(IPv4Address("255.6.7.8")));
}
private void assertInvalidNetworkMask(Inet4Address addr) {
try {
- NetworkUtils.netmaskToPrefixLength(addr);
+ netmaskToPrefixLength(addr);
fail("Invalid netmask " + addr.getHostAddress() + " did not cause exception");
} catch (IllegalArgumentException expected) {
}
}
- @SmallTest
+ @Test
+ public void testInet4AddressToIntHTL() {
+ assertEquals(0, inet4AddressToIntHTL(IPv4Address("0.0.0.0")));
+ assertEquals(0x000080ff, inet4AddressToIntHTL(IPv4Address("255.128.0.0")));
+ assertEquals(0x0080ff0a, inet4AddressToIntHTL(IPv4Address("10.255.128.0")));
+ assertEquals(0x00feff0a, inet4AddressToIntHTL(IPv4Address("10.255.254.0")));
+ assertEquals(0xfeffa8c0, inet4AddressToIntHTL(IPv4Address("192.168.255.254")));
+ assertEquals(0xffffa8c0, inet4AddressToIntHTL(IPv4Address("192.168.255.255")));
+ }
+
+ @Test
+ public void testIntToInet4AddressHTL() {
+ assertEquals(IPv4Address("0.0.0.0"), intToInet4AddressHTL(0));
+ assertEquals(IPv4Address("255.128.0.0"), intToInet4AddressHTL(0x000080ff));
+ assertEquals(IPv4Address("10.255.128.0"), intToInet4AddressHTL(0x0080ff0a));
+ assertEquals(IPv4Address("10.255.254.0"), intToInet4AddressHTL(0x00feff0a));
+ assertEquals(IPv4Address("192.168.255.254"), intToInet4AddressHTL(0xfeffa8c0));
+ assertEquals(IPv4Address("192.168.255.255"), intToInet4AddressHTL(0xffffa8c0));
+ }
+
+ @Test
+ public void testInet4AddressToIntHTH() {
+ assertEquals(0, inet4AddressToIntHTH(IPv4Address("0.0.0.0")));
+ assertEquals(0xff800000, inet4AddressToIntHTH(IPv4Address("255.128.0.0")));
+ assertEquals(0x0aff8000, inet4AddressToIntHTH(IPv4Address("10.255.128.0")));
+ assertEquals(0x0afffe00, inet4AddressToIntHTH(IPv4Address("10.255.254.0")));
+ assertEquals(0xc0a8fffe, inet4AddressToIntHTH(IPv4Address("192.168.255.254")));
+ assertEquals(0xc0a8ffff, inet4AddressToIntHTH(IPv4Address("192.168.255.255")));
+ }
+
+ @Test
+ public void testIntToInet4AddressHTH() {
+ assertEquals(IPv4Address("0.0.0.0"), intToInet4AddressHTH(0));
+ assertEquals(IPv4Address("255.128.0.0"), intToInet4AddressHTH(0xff800000));
+ assertEquals(IPv4Address("10.255.128.0"), intToInet4AddressHTH(0x0aff8000));
+ assertEquals(IPv4Address("10.255.254.0"), intToInet4AddressHTH(0x0afffe00));
+ assertEquals(IPv4Address("192.168.255.254"), intToInet4AddressHTH(0xc0a8fffe));
+ assertEquals(IPv4Address("192.168.255.255"), intToInet4AddressHTH(0xc0a8ffff));
+ }
+
+ @Test
public void testNetmaskToPrefixLength() {
- assertEquals(0, NetworkUtils.netmaskToPrefixLength(IPv4Address("0.0.0.0")));
- assertEquals(9, NetworkUtils.netmaskToPrefixLength(IPv4Address("255.128.0.0")));
- assertEquals(17, NetworkUtils.netmaskToPrefixLength(IPv4Address("255.255.128.0")));
- assertEquals(23, NetworkUtils.netmaskToPrefixLength(IPv4Address("255.255.254.0")));
- assertEquals(31, NetworkUtils.netmaskToPrefixLength(IPv4Address("255.255.255.254")));
- assertEquals(32, NetworkUtils.netmaskToPrefixLength(IPv4Address("255.255.255.255")));
+ assertEquals(0, netmaskToPrefixLength(IPv4Address("0.0.0.0")));
+ assertEquals(9, netmaskToPrefixLength(IPv4Address("255.128.0.0")));
+ assertEquals(17, netmaskToPrefixLength(IPv4Address("255.255.128.0")));
+ assertEquals(23, netmaskToPrefixLength(IPv4Address("255.255.254.0")));
+ assertEquals(31, netmaskToPrefixLength(IPv4Address("255.255.255.254")));
+ assertEquals(32, netmaskToPrefixLength(IPv4Address("255.255.255.255")));
assertInvalidNetworkMask(IPv4Address("0.0.0.1"));
assertInvalidNetworkMask(IPv4Address("255.255.255.253"));
assertInvalidNetworkMask(IPv4Address("255.255.0.255"));
}
- @SmallTest
+ @Test
+ public void testPrefixLengthToV4NetmaskIntHTL() {
+ assertEquals(0, prefixLengthToV4NetmaskIntHTL(0));
+ assertEquals(0x000080ff /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTL(9));
+ assertEquals(0x0080ffff /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTL(17));
+ assertEquals(0x00feffff /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTL(23));
+ assertEquals(0xfeffffff /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTL(31));
+ assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTL(32));
+ }
+
+ @Test
+ public void testPrefixLengthToV4NetmaskIntHTH() {
+ assertEquals(0, prefixLengthToV4NetmaskIntHTH(0));
+ assertEquals(0xff800000 /* 255.128.0.0 */, prefixLengthToV4NetmaskIntHTH(9));
+ assertEquals(0xffff8000 /* 255.255.128.0 */, prefixLengthToV4NetmaskIntHTH(17));
+ assertEquals(0xfffffe00 /* 255.255.254.0 */, prefixLengthToV4NetmaskIntHTH(23));
+ assertEquals(0xfffffffe /* 255.255.255.254 */, prefixLengthToV4NetmaskIntHTH(31));
+ assertEquals(0xffffffff /* 255.255.255.255 */, prefixLengthToV4NetmaskIntHTH(32));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testPrefixLengthToV4NetmaskIntHTH_NegativeLength() {
+ prefixLengthToV4NetmaskIntHTH(-1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testPrefixLengthToV4NetmaskIntHTH_LengthTooLarge() {
+ prefixLengthToV4NetmaskIntHTH(33);
+ }
+
+ private void checkAddressMasking(String expectedAddr, String addr, int prefixLength) {
+ final int prefix = prefixLengthToV4NetmaskIntHTH(prefixLength);
+ final int addrInt = inet4AddressToIntHTH(IPv4Address(addr));
+ assertEquals(IPv4Address(expectedAddr), intToInet4AddressHTH(prefix & addrInt));
+ }
+
+ @Test
+ public void testPrefixLengthToV4NetmaskIntHTH_MaskAddr() {
+ checkAddressMasking("192.168.0.0", "192.168.128.1", 16);
+ checkAddressMasking("255.240.0.0", "255.255.255.255", 12);
+ checkAddressMasking("255.255.255.255", "255.255.255.255", 32);
+ checkAddressMasking("0.0.0.0", "255.255.255.255", 0);
+ }
+
+ @Test
public void testRoutedIPv4AddressCount() {
final TreeSet<IpPrefix> set = new TreeSet<>(IpPrefix.lengthComparator());
// No routes routes to no addresses.
@@ -118,7 +219,7 @@
assertEquals(7l - 4 + 4 + 16 + 65536, NetworkUtils.routedIPv4AddressCount(set));
}
- @SmallTest
+ @Test
public void testRoutedIPv6AddressCount() {
final TreeSet<IpPrefix> set = new TreeSet<>(IpPrefix.lengthComparator());
// No routes routes to no addresses.
@@ -166,4 +267,44 @@
assertEquals(BigInteger.valueOf(7l - 4 + 4 + 16 + 65536),
NetworkUtils.routedIPv6AddressCount(set));
}
+
+ @Test
+ public void testGetPrefixMaskAsAddress() {
+ assertEquals("255.255.240.0", getPrefixMaskAsInet4Address(20).getHostAddress());
+ assertEquals("255.0.0.0", getPrefixMaskAsInet4Address(8).getHostAddress());
+ assertEquals("0.0.0.0", getPrefixMaskAsInet4Address(0).getHostAddress());
+ assertEquals("255.255.255.255", getPrefixMaskAsInet4Address(32).getHostAddress());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetPrefixMaskAsAddress_PrefixTooLarge() {
+ getPrefixMaskAsInet4Address(33);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetPrefixMaskAsAddress_NegativePrefix() {
+ getPrefixMaskAsInet4Address(-1);
+ }
+
+ @Test
+ public void testGetBroadcastAddress() {
+ assertEquals("192.168.15.255",
+ getBroadcastAddress(IPv4Address("192.168.0.123"), 20).getHostAddress());
+ assertEquals("192.255.255.255",
+ getBroadcastAddress(IPv4Address("192.168.0.123"), 8).getHostAddress());
+ assertEquals("192.168.0.123",
+ getBroadcastAddress(IPv4Address("192.168.0.123"), 32).getHostAddress());
+ assertEquals("255.255.255.255",
+ getBroadcastAddress(IPv4Address("192.168.0.123"), 0).getHostAddress());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetBroadcastAddress_PrefixTooLarge() {
+ getBroadcastAddress(IPv4Address("192.168.0.123"), 33);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetBroadcastAddress_NegativePrefix() {
+ getBroadcastAddress(IPv4Address("192.168.0.123"), -1);
+ }
}
diff --git a/tests/net/java/com/android/internal/util/RingBufferTest.java b/tests/net/java/com/android/internal/util/RingBufferTest.java
index 7a23443..90a373a 100644
--- a/tests/net/java/com/android/internal/util/RingBufferTest.java
+++ b/tests/net/java/com/android/internal/util/RingBufferTest.java
@@ -17,6 +17,7 @@
package com.android.internal.util;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import android.support.test.filters.SmallTest;
@@ -129,6 +130,55 @@
assertArraysEqual(expected2, buffer.toArray());
}
+ @Test
+ public void testGetNextSlot() {
+ int capacity = 100;
+ RingBuffer<DummyClass1> buffer = new RingBuffer<>(DummyClass1.class, capacity);
+
+ final DummyClass1[] actual = new DummyClass1[capacity];
+ final DummyClass1[] expected = new DummyClass1[capacity];
+ for (int i = 0; i < capacity; ++i) {
+ final DummyClass1 obj = buffer.getNextSlot();
+ obj.x = capacity * i;
+ actual[i] = obj;
+ expected[i] = new DummyClass1();
+ expected[i].x = capacity * i;
+ }
+ assertArraysEqual(expected, buffer.toArray());
+
+ for (int i = 0; i < capacity; ++i) {
+ if (actual[i] != buffer.getNextSlot()) {
+ fail("getNextSlot() should re-use objects if available");
+ }
+ }
+
+ RingBuffer<DummyClass2> buffer2 = new RingBuffer<>(DummyClass2.class, capacity);
+ assertNull("getNextSlot() should return null if the object can't be initiated "
+ + "(No nullary constructor)", buffer2.getNextSlot());
+
+ RingBuffer<DummyClass3> buffer3 = new RingBuffer<>(DummyClass3.class, capacity);
+ assertNull("getNextSlot() should return null if the object can't be initiated "
+ + "(Inaccessible class)", buffer3.getNextSlot());
+ }
+
+ public static final class DummyClass1 {
+ int x;
+
+ public boolean equals(Object o) {
+ if (o instanceof DummyClass1) {
+ final DummyClass1 other = (DummyClass1) o;
+ return other.x == this.x;
+ }
+ return false;
+ }
+ }
+
+ public static final class DummyClass2 {
+ public DummyClass2(int x) {}
+ }
+
+ private static final class DummyClass3 {}
+
static <T> void assertArraysEqual(T[] expected, T[] got) {
if (expected.length != got.length) {
fail(Arrays.toString(expected) + " and " + Arrays.toString(got)
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 5e5ba4d..e3db7e8 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -62,9 +62,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.eq;
@@ -85,7 +83,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.net.CaptivePortal;
import android.net.ConnectivityManager;
@@ -114,7 +111,6 @@
import android.net.RouteInfo;
import android.net.StringNetworkSpecifier;
import android.net.UidRange;
-import android.net.VpnService;
import android.net.captiveportal.CaptivePortalProbeResult;
import android.net.metrics.IpConnectivityLog;
import android.net.util.MultinetworkPolicyTracker;
@@ -135,7 +131,6 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.mock.MockContentResolver;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
@@ -196,7 +191,16 @@
private static final String TAG = "ConnectivityServiceTest";
private static final int TIMEOUT_MS = 500;
- private static final int TEST_LINGER_DELAY_MS = 120;
+ private static final int TEST_LINGER_DELAY_MS = 250;
+ // Chosen to be less than the linger timeout. This ensures that we can distinguish between a
+ // LOST callback that arrives immediately and a LOST callback that arrives after the linger
+ // timeout. For this, our assertions should run fast enough to leave less than
+ // (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are
+ // supposedly fired, and the time we call expectCallback.
+ private final static int TEST_CALLBACK_TIMEOUT_MS = 200;
+ // Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to
+ // complete before callbacks are verified.
+ private final static int TEST_REQUEST_TIMEOUT_MS = 150;
private static final String CLAT_PREFIX = "v4-";
private static final String MOBILE_IFNAME = "test_rmnet_data0";
@@ -876,7 +880,7 @@
NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest,
IpConnectivityLog log) {
super(context, handler, networkAgentInfo, defaultRequest, log,
- NetworkMonitor.NetworkMonitorSettings.DEFAULT);
+ NetworkMonitor.Dependencies.DEFAULT);
connectivityHandler = handler;
}
@@ -1054,6 +1058,8 @@
mock(INetworkPolicyManager.class),
mock(IpConnectivityLog.class));
+ // Create local CM before sending system ready so that we can answer
+ // getSystemService() correctly.
mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
mService.systemReady();
mService.mockVpn(Process.myUid());
@@ -1463,11 +1469,6 @@
* received. assertNoCallback may be called at any time.
*/
private class TestNetworkCallback extends NetworkCallback {
- // Chosen to be much less than the linger timeout. This ensures that we can distinguish
- // between a LOST callback that arrives immediately and a LOST callback that arrives after
- // the linger timeout.
- private final static int TIMEOUT_MS = 100;
-
private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
private Network mLastAvailableNetwork;
@@ -1543,20 +1544,20 @@
if (state == CallbackState.LOSING) {
String msg = String.format(
"Invalid linger time value %d, must be between %d and %d",
- actual.arg, 0, TEST_LINGER_DELAY_MS);
+ actual.arg, 0, mService.mLingerDelayMs);
int maxMsToLive = (Integer) actual.arg;
- assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= TEST_LINGER_DELAY_MS);
+ assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= mService.mLingerDelayMs);
}
return actual;
}
CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent) {
- return expectCallback(state, agent, TIMEOUT_MS);
+ return expectCallback(state, agent, TEST_CALLBACK_TIMEOUT_MS);
}
CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn) {
- return expectCallbackLike(fn, TIMEOUT_MS);
+ return expectCallbackLike(fn, TEST_CALLBACK_TIMEOUT_MS);
}
CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn, int timeoutMs) {
@@ -1599,15 +1600,15 @@
// Expects the available callbacks (validated), plus onSuspended.
void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent, boolean expectValidated) {
- expectAvailableCallbacks(agent, true, expectValidated, TIMEOUT_MS);
+ expectAvailableCallbacks(agent, true, expectValidated, TEST_CALLBACK_TIMEOUT_MS);
}
void expectAvailableCallbacksValidated(MockNetworkAgent agent) {
- expectAvailableCallbacks(agent, false, true, TIMEOUT_MS);
+ expectAvailableCallbacks(agent, false, true, TEST_CALLBACK_TIMEOUT_MS);
}
void expectAvailableCallbacksUnvalidated(MockNetworkAgent agent) {
- expectAvailableCallbacks(agent, false, false, TIMEOUT_MS);
+ expectAvailableCallbacks(agent, false, false, TEST_CALLBACK_TIMEOUT_MS);
}
// Expects the available callbacks (where the onCapabilitiesChanged must contain the
@@ -1615,9 +1616,9 @@
// one we just sent.
// TODO: this is likely a bug. Fix it and remove this method.
void expectAvailableDoubleValidatedCallbacks(MockNetworkAgent agent) {
- expectCallback(CallbackState.AVAILABLE, agent, TIMEOUT_MS);
+ expectCallback(CallbackState.AVAILABLE, agent, TEST_CALLBACK_TIMEOUT_MS);
NetworkCapabilities nc1 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
- expectCallback(CallbackState.LINK_PROPERTIES, agent, TIMEOUT_MS);
+ expectCallback(CallbackState.LINK_PROPERTIES, agent, TEST_CALLBACK_TIMEOUT_MS);
NetworkCapabilities nc2 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
assertEquals(nc1, nc2);
}
@@ -1631,7 +1632,7 @@
}
NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent) {
- return expectCapabilitiesWith(capability, agent, TIMEOUT_MS);
+ return expectCapabilitiesWith(capability, agent, TEST_CALLBACK_TIMEOUT_MS);
}
NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent,
@@ -1643,7 +1644,7 @@
}
NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent) {
- return expectCapabilitiesWithout(capability, agent, TIMEOUT_MS);
+ return expectCapabilitiesWithout(capability, agent, TEST_CALLBACK_TIMEOUT_MS);
}
NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent,
@@ -1767,6 +1768,12 @@
@Test
public void testMultipleLingering() {
+ // This test would be flaky with the default 120ms timer: that is short enough that
+ // lingered networks are torn down before assertions can be run. We don't want to mock the
+ // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful
+ // in detecting races.
+ mService.mLingerDelayMs = 300;
+
NetworkRequest request = new NetworkRequest.Builder()
.clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED)
.build();
@@ -1984,7 +1991,7 @@
// Let linger run its course.
callback.assertNoCallback();
- final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
+ final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4;
callback.expectCallback(CallbackState.LOST, mCellNetworkAgent, lingerTimeoutMs);
// Register a TRACK_DEFAULT request and check that it does not affect lingering.
@@ -3208,12 +3215,12 @@
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
- final int timeoutMs = 150;
- mCm.requestNetwork(nr, networkCallback, timeoutMs);
+ mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
- networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, timeoutMs);
+ networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+ TEST_CALLBACK_TIMEOUT_MS);
// pass timeout and validate that UNAVAILABLE is not called
networkCallback.assertNoCallback();
@@ -3228,13 +3235,12 @@
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI).build();
final TestNetworkCallback networkCallback = new TestNetworkCallback();
- final int requestTimeoutMs = 50;
- mCm.requestNetwork(nr, networkCallback, requestTimeoutMs);
+ mCm.requestNetwork(nr, networkCallback, TEST_REQUEST_TIMEOUT_MS);
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
- final int assertTimeoutMs = 100;
- networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, assertTimeoutMs);
+ networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+ TEST_CALLBACK_TIMEOUT_MS);
mWiFiNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
@@ -3613,8 +3619,10 @@
@Test
public void testNetworkCallbackMaximum() {
- final int MAX_REQUESTS = 100;
- final int CALLBACKS = 90;
+ // We can only have 99 callbacks, because MultipathPolicyTracker is
+ // already one of them.
+ final int MAX_REQUESTS = 99;
+ final int CALLBACKS = 89;
final int INTENTS = 10;
assertEquals(MAX_REQUESTS, CALLBACKS + INTENTS);
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 1ec4eec..01b468a 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -19,6 +19,9 @@
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
+import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
+import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -40,6 +43,7 @@
import android.test.mock.MockContentResolver;
import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.connectivity.DnsManager.PrivateDnsConfig;
import com.android.server.connectivity.MockableSystemProperties;
import java.net.InetAddress;
@@ -84,10 +88,9 @@
mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties);
// Clear the private DNS settings
- Settings.Global.putString(mContentResolver,
- Settings.Global.PRIVATE_DNS_MODE, "");
- Settings.Global.putString(mContentResolver,
- Settings.Global.PRIVATE_DNS_SPECIFIER, "");
+ Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");
+ Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, "");
+ Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "");
}
@Test
@@ -127,9 +130,8 @@
TEST_IFACENAME));
Settings.Global.putString(mContentResolver,
- Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
- Settings.Global.putString(mContentResolver,
- Settings.Global.PRIVATE_DNS_SPECIFIER, "strictmode.com");
+ PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+ Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
mDnsManager.updatePrivateDns(new Network(TEST_NETID),
new DnsManager.PrivateDnsConfig("strictmode.com", new InetAddress[] {
InetAddress.parseNumericAddress("6.6.6.6"),
@@ -222,8 +224,7 @@
assertNull(lp.getPrivateDnsServerName());
// Turn private DNS mode off
- Settings.Global.putString(mContentResolver,
- Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
+ Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
mDnsManager.updatePrivateDns(new Network(TEST_NETID),
mDnsManager.getPrivateDnsConfig());
mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
@@ -234,4 +235,29 @@
assertFalse(lp.isPrivateDnsActive());
assertNull(lp.getPrivateDnsServerName());
}
+
+ @Test
+ public void testOverrideDefaultMode() throws Exception {
+ // Hard-coded default is opportunistic mode.
+ final PrivateDnsConfig cfgAuto = DnsManager.getPrivateDnsConfig(mContentResolver);
+ assertTrue(cfgAuto.useTls);
+ assertEquals("", cfgAuto.hostname);
+ assertEquals(new InetAddress[0], cfgAuto.ips);
+
+ // Pretend a gservices push sets the default to "off".
+ Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "off");
+ final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mContentResolver);
+ assertFalse(cfgOff.useTls);
+ assertEquals("", cfgOff.hostname);
+ assertEquals(new InetAddress[0], cfgOff.ips);
+
+ // Strict mode still works.
+ Settings.Global.putString(
+ mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+ Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com");
+ final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mContentResolver);
+ assertTrue(cfgStrict.useTls);
+ assertEquals("strictmode.com", cfgStrict.hostname);
+ assertEquals(new InetAddress[0], cfgStrict.ips);
+ }
}
diff --git a/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
new file mode 100644
index 0000000..e58811b
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/MultipathPolicyTrackerTest.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import static android.content.Intent.ACTION_CONFIGURATION_CHANGED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkPolicy.LIMIT_DISABLED;
+import static android.net.NetworkPolicy.SNOOZE_NEVER;
+import static android.net.NetworkPolicy.WARNING_DISABLED;
+import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES;
+
+import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
+import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertNotNull;
+
+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.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.usage.NetworkStatsManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
+import android.net.NetworkTemplate;
+import android.net.StringNetworkSpecifier;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.TelephonyManager;
+import android.test.mock.MockContentResolver;
+import android.util.DataUnit;
+import android.util.RecurrenceRule;
+
+import com.android.internal.R;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.LocalServices;
+import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.net.NetworkStatsManagerInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.temporal.ChronoUnit;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MultipathPolicyTrackerTest {
+ private static final Network TEST_NETWORK = new Network(123);
+ private static final int POLICY_SNOOZED = -100;
+
+ @Mock private Context mContext;
+ @Mock private Resources mResources;
+ @Mock private Handler mHandler;
+ @Mock private MultipathPolicyTracker.Dependencies mDeps;
+ @Mock private Clock mClock;
+ @Mock private ConnectivityManager mCM;
+ @Mock private NetworkPolicyManager mNPM;
+ @Mock private NetworkStatsManager mStatsManager;
+ @Mock private NetworkPolicyManagerInternal mNPMI;
+ @Mock private NetworkStatsManagerInternal mNetworkStatsManagerInternal;
+ @Mock private TelephonyManager mTelephonyManager;
+ private MockContentResolver mContentResolver;
+
+ private ArgumentCaptor<BroadcastReceiver> mConfigChangeReceiverCaptor;
+
+ private MultipathPolicyTracker mTracker;
+
+ private Clock mPreviousRecurrenceRuleClock;
+ private boolean mRecurrenceRuleClockMocked;
+
+ private <T> void mockService(String serviceName, Class<T> serviceClass, T service) {
+ when(mContext.getSystemServiceName(serviceClass)).thenReturn(serviceName);
+ when(mContext.getSystemService(serviceName)).thenReturn(service);
+ }
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mPreviousRecurrenceRuleClock = RecurrenceRule.sClock;
+ RecurrenceRule.sClock = mClock;
+ mRecurrenceRuleClockMocked = true;
+
+ mConfigChangeReceiverCaptor = ArgumentCaptor.forClass(BroadcastReceiver.class);
+
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
+ when(mContext.registerReceiverAsUser(mConfigChangeReceiverCaptor.capture(),
+ any(), argThat(f -> f.hasAction(ACTION_CONFIGURATION_CHANGED)), any(), any()))
+ .thenReturn(null);
+
+ when(mDeps.getClock()).thenReturn(mClock);
+
+ when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
+
+ mContentResolver = Mockito.spy(new MockContentResolver(mContext));
+ mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ Settings.Global.clearProviderForTest();
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+
+ mockService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class, mCM);
+ mockService(Context.NETWORK_POLICY_SERVICE, NetworkPolicyManager.class, mNPM);
+ mockService(Context.NETWORK_STATS_SERVICE, NetworkStatsManager.class, mStatsManager);
+ mockService(Context.TELEPHONY_SERVICE, TelephonyManager.class, mTelephonyManager);
+
+ LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
+ LocalServices.addService(NetworkPolicyManagerInternal.class, mNPMI);
+
+ LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
+ LocalServices.addService(NetworkStatsManagerInternal.class, mNetworkStatsManagerInternal);
+
+ mTracker = new MultipathPolicyTracker(mContext, mHandler, mDeps);
+ }
+
+ @After
+ public void tearDown() {
+ // Avoid setting static clock to null (which should normally not be the case)
+ // if MockitoAnnotations.initMocks threw an exception
+ if (mRecurrenceRuleClockMocked) {
+ RecurrenceRule.sClock = mPreviousRecurrenceRuleClock;
+ }
+ mRecurrenceRuleClockMocked = false;
+ }
+
+ private void setDefaultQuotaGlobalSetting(long setting) {
+ Settings.Global.putInt(mContentResolver, NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES,
+ (int) setting);
+ }
+
+ private void testGetMultipathPreference(
+ long usedBytesToday, long subscriptionQuota, long policyWarning, long policyLimit,
+ long defaultGlobalSetting, long defaultResSetting, boolean roaming) {
+
+ // TODO: tests should not use ZoneId.systemDefault() once code handles TZ correctly.
+ final ZonedDateTime now = ZonedDateTime.ofInstant(
+ Instant.parse("2017-04-02T10:11:12Z"), ZoneId.systemDefault());
+ final ZonedDateTime startOfDay = now.truncatedTo(ChronoUnit.DAYS);
+ when(mClock.millis()).thenReturn(now.toInstant().toEpochMilli());
+ when(mClock.instant()).thenReturn(now.toInstant());
+ when(mClock.getZone()).thenReturn(ZoneId.systemDefault());
+
+ // Setup plan quota
+ when(mNPMI.getSubscriptionOpportunisticQuota(TEST_NETWORK, QUOTA_TYPE_MULTIPATH))
+ .thenReturn(subscriptionQuota);
+
+ // Setup user policy warning / limit
+ if (policyWarning != WARNING_DISABLED || policyLimit != LIMIT_DISABLED) {
+ final Instant recurrenceStart = Instant.parse("2017-04-01T00:00:00Z");
+ final RecurrenceRule recurrenceRule = new RecurrenceRule(
+ ZonedDateTime.ofInstant(
+ recurrenceStart,
+ ZoneId.systemDefault()),
+ null /* end */,
+ Period.ofMonths(1));
+ final boolean snoozeWarning = policyWarning == POLICY_SNOOZED;
+ final boolean snoozeLimit = policyLimit == POLICY_SNOOZED;
+ when(mNPM.getNetworkPolicies()).thenReturn(new NetworkPolicy[] {
+ new NetworkPolicy(
+ NetworkTemplate.buildTemplateMobileWildcard(),
+ recurrenceRule,
+ snoozeWarning ? 0 : policyWarning,
+ snoozeLimit ? 0 : policyLimit,
+ snoozeWarning ? recurrenceStart.toEpochMilli() + 1 : SNOOZE_NEVER,
+ snoozeLimit ? recurrenceStart.toEpochMilli() + 1 : SNOOZE_NEVER,
+ SNOOZE_NEVER,
+ true /* metered */,
+ false /* inferred */)
+ });
+ } else {
+ when(mNPM.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
+ }
+
+ // Setup default quota in settings and resources
+ if (defaultGlobalSetting > 0) {
+ setDefaultQuotaGlobalSetting(defaultGlobalSetting);
+ }
+ when(mResources.getInteger(R.integer.config_networkDefaultDailyMultipathQuotaBytes))
+ .thenReturn((int) defaultResSetting);
+
+ when(mNetworkStatsManagerInternal.getNetworkTotalBytes(
+ any(),
+ eq(startOfDay.toInstant().toEpochMilli()),
+ eq(now.toInstant().toEpochMilli()))).thenReturn(usedBytesToday);
+
+ ArgumentCaptor<ConnectivityManager.NetworkCallback> networkCallback =
+ ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+ mTracker.start();
+ verify(mCM).registerNetworkCallback(any(), networkCallback.capture(), any());
+
+ // Simulate callback after capability changes
+ final NetworkCapabilities capabilities = new NetworkCapabilities()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addTransportType(TRANSPORT_CELLULAR)
+ .setNetworkSpecifier(new StringNetworkSpecifier("234"));
+ if (!roaming) {
+ capabilities.addCapability(NET_CAPABILITY_NOT_ROAMING);
+ }
+ networkCallback.getValue().onCapabilitiesChanged(
+ TEST_NETWORK,
+ capabilities);
+ }
+
+ @Test
+ public void testGetMultipathPreference_SubscriptionQuota() {
+ testGetMultipathPreference(
+ DataUnit.MEGABYTES.toBytes(2) /* usedBytesToday */,
+ DataUnit.MEGABYTES.toBytes(14) /* subscriptionQuota */,
+ DataUnit.MEGABYTES.toBytes(100) /* policyWarning */,
+ LIMIT_DISABLED,
+ DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */,
+ 2_500_000 /* defaultResSetting */,
+ false /* roaming */);
+
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
+ }
+
+ @Test
+ public void testGetMultipathPreference_UserWarningQuota() {
+ testGetMultipathPreference(
+ DataUnit.MEGABYTES.toBytes(7) /* usedBytesToday */,
+ OPPORTUNISTIC_QUOTA_UNKNOWN,
+ // 29 days from Apr. 2nd to May 1st
+ DataUnit.MEGABYTES.toBytes(15 * 29 * 20) /* policyWarning */,
+ LIMIT_DISABLED,
+ DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */,
+ 2_500_000 /* defaultResSetting */,
+ false /* roaming */);
+
+ // Daily budget should be 15MB (5% of daily quota), 7MB used today: callback set for 8MB
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
+ }
+
+ @Test
+ public void testGetMultipathPreference_SnoozedWarningQuota() {
+ testGetMultipathPreference(
+ DataUnit.MEGABYTES.toBytes(7) /* usedBytesToday */,
+ OPPORTUNISTIC_QUOTA_UNKNOWN,
+ // 29 days from Apr. 2nd to May 1st
+ POLICY_SNOOZED /* policyWarning */,
+ DataUnit.MEGABYTES.toBytes(15 * 29 * 20) /* policyLimit */,
+ DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */,
+ 2_500_000 /* defaultResSetting */,
+ false /* roaming */);
+
+ // Daily budget should be 15MB (5% of daily quota), 7MB used today: callback set for 8MB
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
+ }
+
+ @Test
+ public void testGetMultipathPreference_SnoozedBothQuota() {
+ testGetMultipathPreference(
+ DataUnit.MEGABYTES.toBytes(7) /* usedBytesToday */,
+ OPPORTUNISTIC_QUOTA_UNKNOWN,
+ // 29 days from Apr. 2nd to May 1st
+ POLICY_SNOOZED /* policyWarning */,
+ POLICY_SNOOZED /* policyLimit */,
+ DataUnit.MEGABYTES.toBytes(12) /* defaultGlobalSetting */,
+ 2_500_000 /* defaultResSetting */,
+ false /* roaming */);
+
+ // Default global setting should be used: 12 - 7 = 5
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(5)), any(), any());
+ }
+
+ @Test
+ public void testGetMultipathPreference_SettingChanged() {
+ testGetMultipathPreference(
+ DataUnit.MEGABYTES.toBytes(2) /* usedBytesToday */,
+ OPPORTUNISTIC_QUOTA_UNKNOWN,
+ WARNING_DISABLED,
+ LIMIT_DISABLED,
+ -1 /* defaultGlobalSetting */,
+ DataUnit.MEGABYTES.toBytes(10) /* defaultResSetting */,
+ false /* roaming */);
+
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(8)), any(), any());
+
+ // Update setting
+ setDefaultQuotaGlobalSetting(DataUnit.MEGABYTES.toBytes(14));
+ mTracker.mSettingsObserver.onChange(
+ false, Settings.Global.getUriFor(NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES));
+
+ // Callback must have been re-registered with new setting
+ verify(mStatsManager, times(1)).unregisterUsageCallback(any());
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
+ }
+
+ @Test
+ public void testGetMultipathPreference_ResourceChanged() {
+ testGetMultipathPreference(
+ DataUnit.MEGABYTES.toBytes(2) /* usedBytesToday */,
+ OPPORTUNISTIC_QUOTA_UNKNOWN,
+ WARNING_DISABLED,
+ LIMIT_DISABLED,
+ -1 /* defaultGlobalSetting */,
+ DataUnit.MEGABYTES.toBytes(14) /* defaultResSetting */,
+ false /* roaming */);
+
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(12)), any(), any());
+
+ when(mResources.getInteger(R.integer.config_networkDefaultDailyMultipathQuotaBytes))
+ .thenReturn((int) DataUnit.MEGABYTES.toBytes(16));
+
+ final BroadcastReceiver configChangeReceiver = mConfigChangeReceiverCaptor.getValue();
+ assertNotNull(configChangeReceiver);
+ configChangeReceiver.onReceive(mContext, new Intent());
+
+ // Uses the new setting (16 - 2 = 14MB)
+ verify(mStatsManager, times(1)).registerUsageCallback(
+ any(), anyInt(), eq(DataUnit.MEGABYTES.toBytes(14)), any(), any());
+ }
+}
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index 4a83d1b..4dc63f2 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -21,17 +21,22 @@
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.NETWORK_STACK;
-import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -46,6 +51,10 @@
public class PermissionMonitorTest {
private static final int MOCK_UID = 10001;
private static final String[] MOCK_PACKAGE_NAMES = new String[] { "com.foo.bar" };
+ private static final String PARTITION_SYSTEM = "system";
+ private static final String PARTITION_OEM = "oem";
+ private static final String PARTITION_PRODUCT = "product";
+ private static final String PARTITION_VENDOR = "vendor";
@Mock private Context mContext;
@Mock private PackageManager mPackageManager;
@@ -60,39 +69,53 @@
mPermissionMonitor = new PermissionMonitor(mContext, null);
}
- private void expectPermission(String[] permissions, boolean preinstalled) throws Exception {
- final PackageInfo packageInfo = packageInfoWithPermissions(permissions, preinstalled);
- when(mPackageManager.getPackageInfo(MOCK_PACKAGE_NAMES[0], GET_PERMISSIONS))
- .thenReturn(packageInfo);
+ private void expectPermission(String[] permissions, String partition,
+ int targetSdkVersion) throws Exception {
+ final PackageInfo packageInfo = packageInfoWithPermissions(permissions, partition);
+ packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
+ when(mPackageManager.getPackageInfoAsUser(
+ eq(MOCK_PACKAGE_NAMES[0]), eq(GET_PERMISSIONS), anyInt())).thenReturn(packageInfo);
}
- private PackageInfo packageInfoWithPermissions(String[] permissions, boolean preinstalled) {
+ private PackageInfo packageInfoWithPermissions(String[] permissions, String partition) {
final PackageInfo packageInfo = new PackageInfo();
packageInfo.requestedPermissions = permissions;
packageInfo.applicationInfo = new ApplicationInfo();
- packageInfo.applicationInfo.flags = preinstalled ? FLAG_SYSTEM : 0;
+ int privateFlags = 0;
+ switch (partition) {
+ case PARTITION_OEM:
+ privateFlags = PRIVATE_FLAG_OEM;
+ break;
+ case PARTITION_PRODUCT:
+ privateFlags = PRIVATE_FLAG_PRODUCT;
+ break;
+ case PARTITION_VENDOR:
+ privateFlags = PRIVATE_FLAG_VENDOR;
+ break;
+ }
+ packageInfo.applicationInfo.privateFlags = privateFlags;
return packageInfo;
}
@Test
public void testHasPermission() {
- PackageInfo app = packageInfoWithPermissions(new String[] {}, false);
+ PackageInfo app = packageInfoWithPermissions(new String[] {}, PARTITION_SYSTEM);
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
app = packageInfoWithPermissions(new String[] {
- CHANGE_NETWORK_STATE, NETWORK_STACK
- }, false);
+ CHANGE_NETWORK_STATE, NETWORK_STACK
+ }, PARTITION_SYSTEM);
assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
app = packageInfoWithPermissions(new String[] {
- CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL
- }, false);
+ CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL
+ }, PARTITION_SYSTEM);
assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
@@ -100,35 +123,64 @@
}
@Test
- public void testIsPreinstalledSystemApp() {
- PackageInfo app = packageInfoWithPermissions(new String[] {}, false);
- assertFalse(mPermissionMonitor.isPreinstalledSystemApp(app));
-
- app = packageInfoWithPermissions(new String[] {}, true);
- assertTrue(mPermissionMonitor.isPreinstalledSystemApp(app));
+ public void testIsVendorApp() {
+ PackageInfo app = packageInfoWithPermissions(new String[] {}, PARTITION_SYSTEM);
+ assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
+ app = packageInfoWithPermissions(new String[] {}, PARTITION_OEM);
+ assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
+ app = packageInfoWithPermissions(new String[] {}, PARTITION_PRODUCT);
+ assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
+ app = packageInfoWithPermissions(new String[] {}, PARTITION_VENDOR);
+ assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
}
@Test
public void testHasUseBackgroundNetworksPermission() throws Exception {
- expectPermission(new String[] { CHANGE_NETWORK_STATE }, false);
+ expectPermission(new String[] { CHANGE_NETWORK_STATE },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { NETWORK_STACK }, PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_INTERNAL },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_USE_RESTRICTED_NETWORKS },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- expectPermission(new String[] { NETWORK_STACK, CONNECTIVITY_INTERNAL }, false);
+ expectPermission(new String[] { CHANGE_NETWORK_STATE },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { NETWORK_STACK },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_INTERNAL },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CONNECTIVITY_USE_RESTRICTED_NETWORKS },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- // TODO : make this false when b/31479477 is fixed
- expectPermission(new String[] {}, true);
- assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- expectPermission(new String[] { CHANGE_WIFI_STATE }, true);
- assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
-
- expectPermission(new String[] { NETWORK_STACK, CONNECTIVITY_INTERNAL }, true);
- assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
-
- expectPermission(new String[] {}, false);
+ expectPermission(new String[] {}, PARTITION_SYSTEM, Build.VERSION_CODES.P);
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_SYSTEM, Build.VERSION_CODES.P);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] {}, PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_VENDOR, Build.VERSION_CODES.P);
+ assertTrue(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
- expectPermission(new String[] { CHANGE_WIFI_STATE }, false);
+ expectPermission(new String[] {}, PARTITION_SYSTEM, Build.VERSION_CODES.Q);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_SYSTEM, Build.VERSION_CODES.Q);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] {}, PARTITION_VENDOR, Build.VERSION_CODES.Q);
+ assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
+ expectPermission(new String[] { CHANGE_WIFI_STATE },
+ PARTITION_VENDOR, Build.VERSION_CODES.Q);
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID));
}
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
index 23318c2..b870bbd 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsAccessTest.java
@@ -176,7 +176,7 @@
}
private void setHasAppOpsPermission(int appOpsMode, boolean hasPermission) {
- when(mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, TEST_UID, TEST_PKG))
+ when(mAppOps.noteOp(AppOpsManager.OP_GET_USAGE_STATS, TEST_UID, TEST_PKG))
.thenReturn(appOpsMode);
when(mContext.checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)).thenReturn(
hasPermission ? PackageManager.PERMISSION_GRANTED
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 6836626..f89f303 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -91,16 +91,16 @@
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
+import android.os.SimpleClock;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.util.TrustedTime;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.server.LocalServices;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
@@ -116,6 +116,8 @@
import org.mockito.MockitoAnnotations;
import java.io.File;
+import java.time.Clock;
+import java.time.ZoneOffset;
import java.util.Objects;
/**
@@ -160,7 +162,6 @@
private File mStatsDir;
private @Mock INetworkManagementService mNetManager;
- private @Mock TrustedTime mTime;
private @Mock NetworkStatsSettings mSettings;
private @Mock IConnectivityManager mConnManager;
private @Mock IBinder mBinder;
@@ -172,6 +173,13 @@
private INetworkStatsSession mSession;
private INetworkManagementEventObserver mNetworkObserver;
+ private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
+ @Override
+ public long millis() {
+ return currentTimeMillis();
+ }
+ };
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -189,7 +197,7 @@
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mService = new NetworkStatsService(
- mServiceContext, mNetManager, mAlarmManager, wakeLock, mTime,
+ mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock,
TelephonyManager.getDefault(), mSettings, new NetworkStatsObservers(),
mStatsDir, getBaseDir(mStatsDir));
mHandlerThread = new HandlerThread("HandlerThread");
@@ -201,7 +209,6 @@
mElapsedRealtime = 0L;
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsUidDetail(buildEmptyStats());
expectSystemReady();
@@ -226,7 +233,6 @@
mStatsDir = null;
mNetManager = null;
- mTime = null;
mSettings = null;
mConnManager = null;
@@ -238,7 +244,6 @@
public void testNetworkStatsWifi() throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
@@ -253,7 +258,6 @@
// modify some number on wifi, and trigger poll event
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
@@ -267,7 +271,6 @@
// and bump forward again, with counters going higher. this is
// important, since polling should correctly subtract last snapshot.
incrementCurrentTime(DAY_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L));
@@ -285,7 +288,6 @@
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
@@ -300,7 +302,6 @@
// modify some number on wifi, and trigger poll event
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
@@ -329,13 +330,11 @@
// graceful shutdown system, which should trigger persist of stats, and
// clear any values in memory.
- expectCurrentTime();
expectDefaultSettings();
mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
assertStatsFilesExist(true);
// boot through serviceReady() again
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsUidDetail(buildEmptyStats());
expectSystemReady();
@@ -363,7 +362,6 @@
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectCurrentTime();
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
@@ -375,7 +373,6 @@
// modify some number on wifi, and trigger poll event
incrementCurrentTime(2 * HOUR_IN_MILLIS);
- expectCurrentTime();
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
@@ -391,7 +388,6 @@
// now change bucket duration setting and trigger another poll with
// exact same values, which should resize existing buckets.
- expectCurrentTime();
expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -408,7 +404,6 @@
@Test
public void testUidStatsAcrossNetworks() throws Exception {
// pretend first mobile network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
@@ -420,7 +415,6 @@
// create some traffic on first network
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
@@ -442,7 +436,6 @@
// now switch networks; this also tests that we're okay with interfaces
// disappearing, to verify we don't count backwards.
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildMobile3gState(IMSI_2));
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
@@ -459,7 +452,6 @@
// create traffic on second network
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 2176L, 17L, 1536L, 12L));
@@ -488,7 +480,6 @@
@Test
public void testUidRemovedIsMoved() throws Exception {
// pretend that network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
@@ -500,7 +491,6 @@
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
@@ -522,7 +512,6 @@
// now pretend two UIDs are uninstalled, which should migrate stats to
// special "removed" bucket.
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
@@ -550,7 +539,6 @@
@Test
public void testUid3g4gCombinedByTemplate() throws Exception {
// pretend that network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
@@ -562,7 +550,6 @@
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
@@ -578,7 +565,6 @@
// now switch over to 4g network
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildMobile4gState(TEST_IFACE2));
expectNetworkStatsSummary(buildEmptyStats());
@@ -593,7 +579,6 @@
// create traffic on second network
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
@@ -612,7 +597,6 @@
@Test
public void testSummaryForAllUid() throws Exception {
// pretend that network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
@@ -624,7 +608,6 @@
// create some traffic for two apps
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
@@ -642,7 +625,6 @@
// now create more traffic in next hour, but only for one app
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
@@ -762,7 +744,6 @@
@Test
public void testForegroundBackground() throws Exception {
// pretend that network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
@@ -774,7 +755,6 @@
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
@@ -790,7 +770,6 @@
// now switch to foreground
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
@@ -823,7 +802,6 @@
@Test
public void testMetered() throws Exception {
// pretend that network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState(true /* isMetered */));
expectNetworkStatsSummary(buildEmptyStats());
@@ -835,7 +813,6 @@
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
// Note that all traffic from NetworkManagementService is tagged as METERED_NO, ROAMING_NO
@@ -865,7 +842,6 @@
@Test
public void testRoaming() throws Exception {
// pretend that network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildMobile3gState(IMSI_1, true /* isRoaming */));
expectNetworkStatsSummary(buildEmptyStats());
@@ -877,7 +853,6 @@
// Create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
// Note that all traffic from NetworkManagementService is tagged as METERED_NO and
@@ -906,7 +881,6 @@
@Test
public void testTethering() throws Exception {
// pretend first mobile network comes online
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
@@ -918,7 +892,6 @@
// create some tethering traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
// Traffic seen by kernel counters (includes software tethering).
@@ -951,7 +924,6 @@
public void testRegisterUsageCallback() throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
@@ -972,7 +944,6 @@
Messenger messenger = new Messenger(latchedHandler);
// Force poll
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1001,7 +972,6 @@
// modify some number on wifi, and trigger poll event
// not enough traffic to call data usage callback
incrementCurrentTime(HOUR_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L));
@@ -1017,7 +987,6 @@
// and bump forward again, with counters going higher. this is
// important, since it will trigger the data usage callback
incrementCurrentTime(DAY_IN_MILLIS);
- expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
@@ -1160,7 +1129,6 @@
private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
throws Exception {
when(mSettings.getPollInterval()).thenReturn(HOUR_IN_MILLIS);
- when(mSettings.getTimeCacheMaxAge()).thenReturn(DAY_IN_MILLIS);
when(mSettings.getSampleEnabled()).thenReturn(true);
final Config config = new Config(bucketDuration, deleteAge, deleteAge);
@@ -1176,14 +1144,6 @@
when(mSettings.getUidTagPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
}
- private void expectCurrentTime() throws Exception {
- when(mTime.forceRefresh()).thenReturn(false);
- when(mTime.hasCache()).thenReturn(true);
- when(mTime.currentTimeMillis()).thenReturn(currentTimeMillis());
- when(mTime.getCacheAge()).thenReturn(0L);
- when(mTime.getCacheCertainty()).thenReturn(0L);
- }
-
private void expectBandwidthControlCheck() throws Exception {
when(mNetManager.isBandwidthControlEnabled()).thenReturn(true);
}