Merge "Disable mDefaultDns to see if we can remove it." into mnc-dev
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 26878c0..3a3c47d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -611,11 +611,11 @@
/**
* Retrieves the current preferred network type.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an integer representing the preferred network type
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @deprecated Functionality has been removed as it no longer makes sense,
* with many more than two networks - we'd need an array to express
* preference. Instead we use dynamic network properties of
@@ -631,12 +631,11 @@
* You should always check {@link NetworkInfo#isConnected()} before initiating
* network traffic. This may return {@code null} when there is no default
* network.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return a {@link NetworkInfo} object for the current default network
* or {@code null} if no default network is currently active
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*/
public NetworkInfo getActiveNetworkInfo() {
try {
@@ -652,12 +651,11 @@
* network disconnects, the returned {@code Network} object will no longer
* be usable. This will return {@code null} when there is no default
* network.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return a {@link Network} object for the current default network or
* {@code null} if no default network is currently active
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*/
public Network getActiveNetwork() {
try {
@@ -671,13 +669,13 @@
* Returns details about the currently active default data network
* for a given uid. This is for internal use only to avoid spying
* other apps.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
*
* @return a {@link NetworkInfo} object for the current default network
* for the given uid or {@code null} if no default network is
* available for the specified uid.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
* {@hide}
*/
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
@@ -691,6 +689,8 @@
/**
* Returns connection status information about a particular
* network type.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param networkType integer specifying which networkType in
* which you're interested.
@@ -698,9 +698,6 @@
* network type or {@code null} if the type is not
* supported by the device.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- *
* @deprecated This method does not support multiple connected networks
* of the same type. Use {@link #getAllNetworks} and
* {@link #getNetworkInfo(android.net.Network)} instead.
@@ -716,15 +713,14 @@
/**
* Returns connection status information about a particular
* Network.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param network {@link Network} specifying which network
* in which you're interested.
* @return a {@link NetworkInfo} object for the requested
* network or {@code null} if the {@code Network}
* is not valid.
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*/
public NetworkInfo getNetworkInfo(Network network) {
try {
@@ -737,13 +733,12 @@
/**
* Returns connection status information about all network
* types supported by the device.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an array of {@link NetworkInfo} objects. Check each
* {@link NetworkInfo#getType} for which type each applies.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- *
* @deprecated This method does not support multiple connected networks
* of the same type. Use {@link #getAllNetworks} and
* {@link #getNetworkInfo(android.net.Network)} instead.
@@ -779,11 +774,10 @@
/**
* Returns an array of all {@link Network} currently tracked by the
* framework.
- *
- * @return an array of {@link Network} objects.
- *
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ *
+ * @return an array of {@link Network} objects.
*/
public Network[] getAllNetworks() {
try {
@@ -812,13 +806,12 @@
* You should always check {@link NetworkInfo#isConnected()} before initiating
* network traffic. This may return {@code null} when there is no default
* network.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return a {@link NetworkInfo} object for the current default network
* or {@code null} if no default network is currently active
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
- *
* {@hide}
*/
public NetworkInfo getProvisioningOrActiveNetworkInfo() {
@@ -831,13 +824,13 @@
/**
* Returns the IP information for the current default network.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return a {@link LinkProperties} object describing the IP info
* for the current default network, or {@code null} if there
* is no current default network.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public LinkProperties getActiveLinkProperties() {
@@ -850,14 +843,14 @@
/**
* Returns the IP information for a given network type.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param networkType the network type of interest.
* @return a {@link LinkProperties} object describing the IP info
* for the given networkType, or {@code null} if there is
* no current default network.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
* @deprecated This method does not support multiple connected networks
* of the same type. Use {@link #getAllNetworks},
@@ -875,10 +868,12 @@
/**
* Get the {@link LinkProperties} for the given {@link Network}. This
* will return {@code null} if the network is unknown.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param network The {@link Network} object identifying the network in question.
* @return The {@link LinkProperties} for the network, or {@code null}.
- **/
+ */
public LinkProperties getLinkProperties(Network network) {
try {
return mService.getLinkProperties(network);
@@ -890,6 +885,8 @@
/**
* Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This
* will return {@code null} if the network is unknown.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param network The {@link Network} object identifying the network in question.
* @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
@@ -1493,11 +1490,11 @@
/**
* Get the set of tetherable, available interfaces. This list is limited by
* device configuration and current interface existence.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an array of 0 or more Strings of tetherable interface names.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableIfaces() {
@@ -1510,11 +1507,11 @@
/**
* Get the set of tethered interfaces.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an array of 0 or more String of currently tethered interface names.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetheredIfaces() {
@@ -1532,12 +1529,12 @@
* may cause them to reset to the available state.
* {@link ConnectivityManager#getLastTetherError} can be used to get more
* information on the cause of the errors.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an array of 0 or more String indicating the interface names
* which failed to tether.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetheringErroredIfaces() {
@@ -1570,12 +1567,12 @@
* allowed between the tethered devices and this device, though upstream net
* access will of course fail until an upstream network interface becomes
* active.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
*
* @param iface the interface name to tether.
* @return error a {@code TETHER_ERROR} value indicating success or failure type
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* {@hide}
*/
public int tether(String iface) {
@@ -1588,12 +1585,12 @@
/**
* Stop tethering the named interface.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
*
* @param iface the interface name to untether.
* @return error a {@code TETHER_ERROR} value indicating success or failure type
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* {@hide}
*/
public int untether(String iface) {
@@ -1608,11 +1605,11 @@
* Check if the device allows for tethering. It may be disabled via
* {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
* due to device configuration.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return a boolean - {@code true} indicating Tethering is supported.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public boolean isTetheringSupported() {
@@ -1627,12 +1624,12 @@
* Get the list of regular expressions that define any tetherable
* USB network interfaces. If USB tethering is not supported by the
* device, this list should be empty.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an array of 0 or more regular expression Strings defining
* what interfaces are considered tetherable usb interfaces.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableUsbRegexs() {
@@ -1647,12 +1644,12 @@
* Get the list of regular expressions that define any tetherable
* Wifi network interfaces. If Wifi tethering is not supported by the
* device, this list should be empty.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an array of 0 or more regular expression Strings defining
* what interfaces are considered tetherable wifi interfaces.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableWifiRegexs() {
@@ -1667,12 +1664,12 @@
* Get the list of regular expressions that define any tetherable
* Bluetooth network interfaces. If Bluetooth tethering is not supported by the
* device, this list should be empty.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return an array of 0 or more regular expression Strings defining
* what interfaces are considered tetherable bluetooth interfaces.
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableBluetoothRegexs() {
@@ -1689,12 +1686,12 @@
* attempt to switch to Rndis and subsequently tether the resulting
* interface on {@code true} or turn off tethering and switch off
* Rndis on {@code false}.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
*
* @param enable a boolean - {@code true} to enable tethering
* @return error a {@code TETHER_ERROR} value indicating success or failure type
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* {@hide}
*/
public int setUsbTethering(boolean enable) {
@@ -1731,13 +1728,13 @@
/**
* Get a more detailed error code after a Tethering or Untethering
* request asynchronously failed.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param iface The name of the interface of interest
* @return error The error code of the last error tethering or untethering the named
* interface
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public int getLastTetherError(String iface) {
@@ -1751,12 +1748,11 @@
/**
* Report network connectivity status. This is currently used only
* to alter status bar UI.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#STATUS_BAR}.
*
* @param networkType The type of network you want to report on
* @param percentage The quality of the connection 0 is bad, 100 is good
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#STATUS_BAR}.
* {@hide}
*/
public void reportInetCondition(int networkType, int percentage) {
@@ -1886,12 +1882,11 @@
* for typical HTTP proxies - they are general network dependent. However if you're
* doing something unusual like general internal filtering this may be useful. On
* a private network where the proxy is not accessible, you may break HTTP using this.
- *
- * @param p The a {@link ProxyInfo} object defining the new global
- * HTTP proxy. A {@code null} value will clear the global HTTP proxy.
- *
* <p>This method requires the caller to hold the permission
* android.Manifest.permission#CONNECTIVITY_INTERNAL.
+ *
+ * @param p A {@link ProxyInfo} object defining the new global
+ * HTTP proxy. A {@code null} value will clear the global HTTP proxy.
* @hide
*/
public void setGlobalProxy(ProxyInfo p) {
@@ -1906,9 +1901,6 @@
*
* @return {@link ProxyInfo} for the current global HTTP proxy or {@code null}
* if no global HTTP proxy is set.
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @hide
*/
public ProxyInfo getGlobalProxy() {
@@ -1920,6 +1912,28 @@
}
/**
+ * Retrieve the global HTTP proxy, or if no global HTTP proxy is set, a
+ * network-specific HTTP proxy. If {@code network} is null, the
+ * network-specific proxy returned is the proxy of the default active
+ * network.
+ *
+ * @return {@link ProxyInfo} for the current global HTTP proxy, or if no
+ * global HTTP proxy is set, {@code ProxyInfo} for {@code network},
+ * or when {@code network} is {@code null},
+ * the {@code ProxyInfo} for the default active network. Returns
+ * {@code null} when no proxy applies or the caller doesn't have
+ * permission to use {@code network}.
+ * @hide
+ */
+ public ProxyInfo getProxyForNetwork(Network network) {
+ try {
+ return mService.getProxyForNetwork(network);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Get the current default HTTP proxy settings. If a global proxy is set it will be returned,
* otherwise if this process is bound to a {@link Network} using
* {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
@@ -1929,19 +1943,7 @@
* HTTP proxy is active.
*/
public ProxyInfo getDefaultProxy() {
- final Network network = getBoundNetworkForProcess();
- if (network != null) {
- final ProxyInfo globalProxy = getGlobalProxy();
- if (globalProxy != null) return globalProxy;
- final LinkProperties lp = getLinkProperties(network);
- if (lp != null) return lp.getHttpProxy();
- return null;
- }
- try {
- return mService.getDefaultProxy();
- } catch (RemoteException e) {
- return null;
- }
+ return getProxyForNetwork(getBoundNetworkForProcess());
}
/**
@@ -1951,12 +1953,12 @@
* hardware supports it. For example a GSM phone without a SIM
* should still return {@code true} for mobile data, but a wifi only
* tablet would return {@code false}.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param networkType The network type we'd like to check
* @return {@code true} if supported, else {@code false}
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @hide
*/
public boolean isNetworkSupported(int networkType) {
@@ -1973,12 +1975,11 @@
* battery/performance issues. You should check this before doing large
* data transfers, and warn the user or delay the operation until another
* network is available.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @return {@code true} if large transfers should be avoided, otherwise
* {@code false}.
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*/
public boolean isActiveNetworkMetered() {
try {
@@ -2008,13 +2009,12 @@
/**
* Signal that the captive portal check on the indicated network
* is complete and whether its a captive portal or not.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
*
* @param info the {@link NetworkInfo} object for the networkType
* in question.
* @param isCaptivePortal true/false.
- *
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
* {@hide}
*/
public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
@@ -2086,11 +2086,11 @@
/**
* Set the value for enabling/disabling airplane mode
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
*
* @param enable whether to enable airplane mode or not
*
- * <p>This method requires the caller to hold the permission
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
* @hide
*/
public void setAirplaneMode(boolean enable) {
@@ -2431,6 +2431,8 @@
* Status of the request can be followed by listening to the various
* callbacks described in {@link NetworkCallback}. The {@link Network}
* can be used to direct traffic to the network.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
*
* @param request {@link NetworkRequest} describing this request.
* @param networkCallback The {@link NetworkCallback} to be utilized for this
@@ -2450,6 +2452,8 @@
* network is not found within the given time (in milliseconds) the
* {@link NetworkCallback#unavailable} callback is called. The request must
* still be released normally by calling {@link releaseNetworkRequest}.
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* @param request {@link NetworkRequest} describing this request.
* @param networkCallback The callbacks to be utilized for this request. Note
* the callbacks must not be shared - they uniquely specify
@@ -2515,7 +2519,8 @@
* <p>
* The request may be released normally by calling
* {@link #releaseNetworkRequest(android.app.PendingIntent)}.
- *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* @param request {@link NetworkRequest} describing this request.
* @param operation Action to perform when the network is available (corresponds
* to the {@link NetworkCallback#onAvailable} call. Typically
@@ -2556,6 +2561,8 @@
* Registers to receive notifications about all networks which satisfy the given
* {@link NetworkRequest}. The callbacks will continue to be called until
* either the application exits or {@link #unregisterNetworkCallback} is called
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*
* @param request {@link NetworkRequest} describing this request.
* @param networkCallback The {@link NetworkCallback} that the system will call as suitable
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index c1b4a1f..89d23a2 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -104,7 +104,7 @@
void setGlobalProxy(in ProxyInfo p);
- ProxyInfo getDefaultProxy();
+ ProxyInfo getProxyForNetwork(in Network nework);
boolean prepareVpn(String oldPackage, String newPackage, int userId);
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 8b0dfc9..31aedad 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -88,6 +88,54 @@
/**
* @hide
*/
+ public enum ProvisioningChange {
+ STILL_NOT_PROVISIONED,
+ LOST_PROVISIONING,
+ GAINED_PROVISIONING,
+ STILL_PROVISIONED,
+ }
+
+ /**
+ * Compare the provisioning states of two LinkProperties instances.
+ *
+ * @hide
+ */
+ public static ProvisioningChange compareProvisioning(
+ LinkProperties before, LinkProperties after) {
+ if (before.isProvisioned() && after.isProvisioned()) {
+ // On dualstack networks, DHCPv4 renewals can occasionally fail.
+ // When this happens, IPv6-reachable services continue to function
+ // normally but IPv4-only services (naturally) fail.
+ //
+ // When an application using an IPv4-only service reports a bad
+ // network condition to the framework, attempts to re-validate
+ // the network succeed (since we support IPv6-only networks) and
+ // nothing is changed.
+ //
+ // For users, this is confusing and unexpected behaviour, and is
+ // not necessarily easy to diagnose. Therefore, we treat changing
+ // from a dualstack network to an IPv6-only network equivalent to
+ // a total loss of provisioning.
+ //
+ // For one such example of this, see b/18867306.
+ //
+ // TODO: Remove this special case altogether.
+ if (before.isIPv4Provisioned() && !after.isIPv4Provisioned()) {
+ return ProvisioningChange.LOST_PROVISIONING;
+ }
+ return ProvisioningChange.STILL_PROVISIONED;
+ } else if (before.isProvisioned() && !after.isProvisioned()) {
+ return ProvisioningChange.LOST_PROVISIONING;
+ } else if (!before.isProvisioned() && after.isProvisioned()) {
+ return ProvisioningChange.GAINED_PROVISIONING;
+ } else { // !before.isProvisioned() && !after.isProvisioned()
+ return ProvisioningChange.STILL_NOT_PROVISIONED;
+ }
+ }
+
+ /**
+ * @hide
+ */
public LinkProperties() {
}
@@ -287,6 +335,20 @@
}
/**
+ * Removes the given {@link InetAddress} from the list of DNS servers.
+ *
+ * @param dnsServer The {@link InetAddress} to remove from the list of DNS servers.
+ * @return true if the DNS server was removed, false if it did not exist.
+ * @hide
+ */
+ public boolean removeDnsServer(InetAddress dnsServer) {
+ if (dnsServer != null) {
+ return mDnses.remove(dnsServer);
+ }
+ return false;
+ }
+
+ /**
* Replaces the DNS servers in this {@code LinkProperties} with
* the given {@link Collection} of {@link InetAddress} objects.
*
@@ -679,8 +741,9 @@
* This requires an IP address, default route, and DNS server.
*
* @return {@code true} if the link is provisioned, {@code false} otherwise.
+ * @hide
*/
- private boolean hasIPv4() {
+ public boolean isIPv4Provisioned() {
return (hasIPv4Address() &&
hasIPv4DefaultRoute() &&
hasIPv4DnsServer());
@@ -691,8 +754,9 @@
* This requires an IP address, default route, and DNS server.
*
* @return {@code true} if the link is provisioned, {@code false} otherwise.
+ * @hide
*/
- private boolean hasIPv6() {
+ public boolean isIPv6Provisioned() {
return (hasGlobalIPv6Address() &&
hasIPv6DefaultRoute() &&
hasIPv6DnsServer());
@@ -706,7 +770,7 @@
* @hide
*/
public boolean isProvisioned() {
- return (hasIPv4() || hasIPv6());
+ return (isIPv4Provisioned() || isIPv6Provisioned());
}
/**
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 67ecb5d..754c6b3 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -247,12 +247,7 @@
throw new IOException("No ConnectivityManager yet constructed, please construct one");
}
// TODO: Should this be optimized to avoid fetching the global proxy for every request?
- ProxyInfo proxyInfo = cm.getGlobalProxy();
- if (proxyInfo == null) {
- // TODO: Should this be optimized to avoid fetching LinkProperties for every request?
- final LinkProperties lp = cm.getLinkProperties(this);
- if (lp != null) proxyInfo = lp.getHttpProxy();
- }
+ final ProxyInfo proxyInfo = cm.getProxyForNetwork(this);
java.net.Proxy proxy = null;
if (proxyInfo != null) {
proxy = proxyInfo.makeProxy();
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 9c3a623..e6fc1ea 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -27,6 +27,7 @@
import com.android.internal.util.Protocol;
import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* A Utility class for handling for communicating between bearer-specific
@@ -51,6 +52,8 @@
private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
private volatile long mLastBwRefreshTime = 0;
private static final long BW_REFRESH_MIN_WIN_MS = 500;
+ private boolean mPollLceScheduled = false;
+ private AtomicBoolean mPollLcePending = new AtomicBoolean(false);
private static final int BASE = Protocol.BASE_NETWORK_AGENT;
@@ -207,11 +210,23 @@
break;
}
case CMD_REQUEST_BANDWIDTH_UPDATE: {
+ long currentTimeMs = System.currentTimeMillis();
if (VDBG) {
log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
}
- if (System.currentTimeMillis() > (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
- pollLceData();
+ if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
+ mPollLceScheduled = false;
+ if (mPollLcePending.getAndSet(true) == false) {
+ pollLceData();
+ }
+ } else {
+ // deliver the request at a later time rather than discard it completely.
+ if (!mPollLceScheduled) {
+ long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS -
+ currentTimeMs + 1;
+ mPollLceScheduled = sendEmptyMessageDelayed(
+ CMD_REQUEST_BANDWIDTH_UPDATE, waitTime);
+ }
}
break;
}
@@ -260,6 +275,7 @@
* Called by the bearer code when it has new NetworkCapabilities data.
*/
public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
+ mPollLcePending.set(false);
mLastBwRefreshTime = System.currentTimeMillis();
queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
new NetworkCapabilities(networkCapabilities));
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 29dd8ad..4487cab 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -194,6 +194,12 @@
public native static boolean protectFromVpn(int socketfd);
/**
+ * Determine if {@code uid} can access network designated by {@code netId}.
+ * @return {@code true} if {@code uid} can access network, {@code false} otherwise.
+ */
+ 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
*/
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index 2c90909..5f5e623 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -35,13 +35,7 @@
*
* Other HTTP stacks will need to obtain the proxy info from
* {@link Proxy#PROXY_CHANGE_ACTION} broadcast as the extra {@link Proxy#EXTRA_PROXY_INFO}.
- *
- * @deprecated Please use {@link java.net.URL#openConnection}, {@link java.net.Proxy} and
- * friends. The Apache HTTP client is no longer maintained and may be removed in a future
- * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a>
- * for further details.
*/
-@Deprecated
public class ProxyInfo implements Parcelable {
private String mHost;
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 60e8ed0..fada7ac 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -291,6 +291,11 @@
return (jboolean) !protectFromVpn(socket);
}
+static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jint uid, jint netId)
+{
+ return (jboolean) !queryUserAccess(uid, netId);
+}
+
// ----------------------------------------------------------------------------
@@ -311,6 +316,7 @@
{ "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
{ "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
{ "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
+ { "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
{ "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDhcpFilter },
};
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index abfed6e..5c55efb 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -17,6 +17,7 @@
package android.net;
import android.net.LinkProperties;
+import android.net.LinkProperties.ProvisioningChange;
import android.net.RouteInfo;
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
@@ -34,7 +35,8 @@
private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888");
private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
- private static InetAddress GATEWAY6 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
+ private static InetAddress GATEWAY61 = NetworkUtils.numericToInetAddress("fe80::6:0000:613");
+ private static InetAddress GATEWAY62 = NetworkUtils.numericToInetAddress("fe80::6:2222");
private static String NAME = "qmi0";
private static int MTU = 1500;
@@ -466,6 +468,8 @@
assertFalse("v4only:addr+dns", lp4.isProvisioned());
lp4.addRoute(new RouteInfo(GATEWAY1));
assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
+ assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned());
+ assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned());
LinkProperties lp6 = new LinkProperties();
assertFalse("v6only:empty", lp6.isProvisioned());
@@ -473,11 +477,14 @@
assertFalse("v6only:fe80-only", lp6.isProvisioned());
lp6.addDnsServer(DNS6);
assertFalse("v6only:fe80+dns", lp6.isProvisioned());
- lp6.addRoute(new RouteInfo(GATEWAY6));
+ lp6.addRoute(new RouteInfo(GATEWAY61));
assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
lp6.addLinkAddress(LINKADDRV6);
+ assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned());
assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
+ assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned());
+ assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned());
assertTrue("v6only:global+dns+route", lp6.isProvisioned());
LinkProperties lp46 = new LinkProperties();
@@ -487,15 +494,77 @@
lp46.addDnsServer(DNS6);
assertFalse("dualstack:missing-routes", lp46.isProvisioned());
lp46.addRoute(new RouteInfo(GATEWAY1));
+ assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned());
+ assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned());
assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
- lp6.addRoute(new RouteInfo(GATEWAY6));
+ lp46.addRoute(new RouteInfo(GATEWAY61));
+ assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned());
+ assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned());
assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
// A link with an IPv6 address and default route, but IPv4 DNS server.
LinkProperties mixed = new LinkProperties();
mixed.addLinkAddress(LINKADDRV6);
mixed.addDnsServer(DNS1);
- mixed.addRoute(new RouteInfo(GATEWAY6));
+ mixed.addRoute(new RouteInfo(GATEWAY61));
+ assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned());
+ assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned());
assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
}
+
+ @SmallTest
+ public void testCompareProvisioning() {
+ LinkProperties v4lp = new LinkProperties();
+ v4lp.addLinkAddress(LINKADDRV4);
+ v4lp.addRoute(new RouteInfo(GATEWAY1));
+ v4lp.addDnsServer(DNS1);
+ assertTrue(v4lp.isProvisioned());
+
+ LinkProperties v4r = new LinkProperties(v4lp);
+ v4r.removeDnsServer(DNS1);
+ assertFalse(v4r.isProvisioned());
+
+ assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
+ LinkProperties.compareProvisioning(v4r, v4r));
+ assertEquals(ProvisioningChange.LOST_PROVISIONING,
+ LinkProperties.compareProvisioning(v4lp, v4r));
+ assertEquals(ProvisioningChange.GAINED_PROVISIONING,
+ LinkProperties.compareProvisioning(v4r, v4lp));
+ assertEquals(ProvisioningChange.STILL_PROVISIONED,
+ LinkProperties.compareProvisioning(v4lp, v4lp));
+
+ // Check that losing IPv4 provisioning on a dualstack network is
+ // seen as a total loss of provisioning.
+ LinkProperties v6lp = new LinkProperties();
+ v6lp.addLinkAddress(LINKADDRV6);
+ v6lp.addRoute(new RouteInfo(GATEWAY61));
+ v6lp.addDnsServer(DNS6);
+ assertFalse(v6lp.isIPv4Provisioned());
+ assertTrue(v6lp.isIPv6Provisioned());
+ assertTrue(v6lp.isProvisioned());
+
+ LinkProperties v46lp = new LinkProperties(v6lp);
+ v46lp.addLinkAddress(LINKADDRV4);
+ v46lp.addRoute(new RouteInfo(GATEWAY1));
+ v46lp.addDnsServer(DNS1);
+ assertTrue(v46lp.isIPv4Provisioned());
+ assertTrue(v46lp.isIPv6Provisioned());
+ assertTrue(v46lp.isProvisioned());
+
+ assertEquals(ProvisioningChange.STILL_PROVISIONED,
+ LinkProperties.compareProvisioning(v6lp, v46lp));
+ assertEquals(ProvisioningChange.LOST_PROVISIONING,
+ LinkProperties.compareProvisioning(v46lp, v6lp));
+
+ // Check that losing and gaining a secondary router does not change
+ // the provisioning status.
+ LinkProperties v6lp2 = new LinkProperties(v6lp);
+ v6lp2.addRoute(new RouteInfo(GATEWAY62));
+ assertTrue(v6lp2.isProvisioned());
+
+ assertEquals(ProvisioningChange.STILL_PROVISIONED,
+ LinkProperties.compareProvisioning(v6lp2, v6lp));
+ assertEquals(ProvisioningChange.STILL_PROVISIONED,
+ LinkProperties.compareProvisioning(v6lp, v6lp2));
+ }
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4be33a4..2e4b881 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -199,7 +199,6 @@
// 0 is full bad, 100 is full good
private int mDefaultInetConditionPublished = 0;
- private Object mDnsLock = new Object();
private int mNumDnsEntries;
private boolean mTestMode;
@@ -543,16 +542,24 @@
}
public void dump(IndentingPrintWriter pw) {
+ pw.println("mLegacyTypeTracker:");
+ pw.increaseIndent();
+ pw.print("Supported types:");
for (int type = 0; type < mTypeLists.length; type++) {
- if (mTypeLists[type] == null) continue;
- pw.print(type + " ");
- pw.increaseIndent();
- if (mTypeLists[type].size() == 0) pw.println("none");
- for (NetworkAgentInfo nai : mTypeLists[type]) {
- pw.println(naiToString(nai));
- }
- pw.decreaseIndent();
+ if (mTypeLists[type] != null) pw.print(" " + type);
}
+ pw.println();
+ pw.println("Current state:");
+ pw.increaseIndent();
+ for (int type = 0; type < mTypeLists.length; type++) {
+ if (mTypeLists[type] == null|| mTypeLists[type].size() == 0) continue;
+ for (NetworkAgentInfo nai : mTypeLists[type]) {
+ pw.println(type + " " + naiToString(nai));
+ }
+ }
+ pw.decreaseIndent();
+ pw.decreaseIndent();
+ pw.println();
}
// This class needs its own log method because it has a different TAG.
@@ -1750,12 +1757,11 @@
return;
}
- pw.println("NetworkFactories for:");
- pw.increaseIndent();
+ pw.print("NetworkFactories for:");
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- pw.println(nfi.name);
+ pw.print(" " + nfi.name);
}
- pw.decreaseIndent();
+ pw.println();
pw.println();
NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
@@ -1795,22 +1801,22 @@
pw.println();
pw.decreaseIndent();
- pw.println("mLegacyTypeTracker:");
- pw.increaseIndent();
mLegacyTypeTracker.dump(pw);
- pw.decreaseIndent();
- pw.println();
synchronized (this) {
- pw.println("NetworkTransitionWakeLock is currently " +
- (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
- pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
+ pw.print("mNetTransitionWakeLock: currently " +
+ (mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held");
+ if (!TextUtils.isEmpty(mNetTransitionWakeLockCausedBy)) {
+ pw.println(", last requested for " + mNetTransitionWakeLockCausedBy);
+ } else {
+ pw.println(", last requested never");
+ }
}
pw.println();
mTethering.dump(fd, pw, args);
- if (mInetLog != null) {
+ if (mInetLog != null && mInetLog.size() > 0) {
pw.println();
pw.println("Inet condition reports:");
pw.increaseIndent();
@@ -2688,7 +2694,7 @@
actionToken);
}
- public ProxyInfo getDefaultProxy() {
+ private ProxyInfo getDefaultProxy() {
// this information is already available as a world read/writable jvm property
// so this API change wouldn't have a benifit. It also breaks the passing
// of proxy info to all the JVMs.
@@ -2700,6 +2706,22 @@
}
}
+ public ProxyInfo getProxyForNetwork(Network network) {
+ if (network == null) return getDefaultProxy();
+ final ProxyInfo globalProxy = getGlobalProxy();
+ if (globalProxy != null) return globalProxy;
+ if (!NetworkUtils.queryUserAccess(Binder.getCallingUid(), network.netId)) return null;
+ // Don't call getLinkProperties() as it requires ACCESS_NETWORK_STATE permission, which
+ // caller may not have.
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (nai == null) return null;
+ synchronized (nai) {
+ final ProxyInfo proxyInfo = nai.linkProperties.getHttpProxy();
+ if (proxyInfo == null) return null;
+ return new ProxyInfo(proxyInfo);
+ }
+ }
+
// Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
// (e.g. if mGlobalProxy==null fall back to network-specific proxy, if network-specific
// proxy is null then there is no proxy in place).
@@ -3624,6 +3646,7 @@
@Override
public void releasePendingNetworkRequest(PendingIntent operation) {
+ checkNotNull(operation, "PendingIntent cannot be null.");
mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
getCallingUid(), 0, operation));
}
@@ -4588,27 +4611,36 @@
@Override
public void factoryReset() {
enforceConnectivityInternalPermission();
+
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
+ return;
+ }
+
final int userId = UserHandle.getCallingUserId();
// Turn airplane mode off
setAirplaneMode(false);
- // Untether
- for (String tether : getTetheredIfaces()) {
- untether(tether);
+ if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
+ // Untether
+ for (String tether : getTetheredIfaces()) {
+ untether(tether);
+ }
}
- // Turn VPN off
- VpnConfig vpnConfig = getVpnConfig(userId);
- if (vpnConfig != null) {
- if (vpnConfig.legacy) {
- prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
- } else {
- // Prevent this app (packagename = vpnConfig.user) from initiating VPN connections
- // in the future without user intervention.
- setVpnPackageAuthorization(vpnConfig.user, userId, false);
+ if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
+ // Turn VPN off
+ VpnConfig vpnConfig = getVpnConfig(userId);
+ if (vpnConfig != null) {
+ if (vpnConfig.legacy) {
+ prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN, userId);
+ } else {
+ // Prevent this app (packagename = vpnConfig.user) from initiating VPN connections
+ // in the future without user intervention.
+ setVpnPackageAuthorization(vpnConfig.user, userId, false);
- prepareVpn(vpnConfig.user, VpnConfig.LEGACY_VPN, userId);
+ prepareVpn(vpnConfig.user, VpnConfig.LEGACY_VPN, userId);
+ }
}
}
}