Merge "Don't send spurious onAvailable NetworkCallbacks when rematching" into mnc-dev
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3a3c47d..a2ca41c 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -801,28 +801,6 @@
}
/**
- * Returns details about the Provisioning or currently active default data network. When
- * connected, this network is the default route for outgoing connections.
- * 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
- *
- * {@hide}
- */
- public NetworkInfo getProvisioningOrActiveNetworkInfo() {
- try {
- return mService.getProvisioningOrActiveNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
* 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}.
@@ -2007,24 +1985,6 @@
}
/**
- * 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.
- * {@hide}
- */
- public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
- try {
- mService.captivePortalCheckCompleted(info, isCaptivePortal);
- } catch (RemoteException e) {
- }
- }
-
- /**
* Check mobile provisioning.
*
* @param suggestedTimeOutMs, timeout in milliseconds
@@ -2056,18 +2016,6 @@
}
/**
- * Get the mobile redirected provisioning url.
- * {@hide}
- */
- public String getMobileRedirectedProvisioningUrl() {
- try {
- return mService.getMobileRedirectedProvisioningUrl();
- } catch (RemoteException e) {
- }
- return null;
- }
-
- /**
* Set sign in error notification to visible or in visible
*
* @param visible
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 89d23a2..29557bb 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -53,8 +53,6 @@
Network[] getAllNetworks();
NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId);
- NetworkInfo getProvisioningOrActiveNetworkInfo();
-
boolean isNetworkSupported(int networkType);
LinkProperties getActiveLinkProperties();
@@ -122,14 +120,10 @@
boolean updateLockdownVpn();
- void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
-
int checkMobileProvisioning(int suggestedTimeOutMs);
String getMobileProvisioningUrl();
- String getMobileRedirectedProvisioningUrl();
-
void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
void setAirplaneMode(boolean enable);
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 9628bae..fe69320 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -378,6 +378,9 @@
//
// The HANDLE_MAGIC 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 HANDLE_MAGIC = 0xfacade;
return (((long) netId) << 32) | HANDLE_MAGIC;
}
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 393637e..af7a465 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -120,7 +120,6 @@
private String mExtraInfo;
private boolean mIsFailover;
private boolean mIsRoaming;
- private boolean mIsConnectedToProvisioningNetwork;
/**
* Indicates whether network connectivity is possible:
@@ -142,7 +141,6 @@
mState = State.UNKNOWN;
mIsAvailable = false; // until we're told otherwise, assume unavailable
mIsRoaming = false;
- mIsConnectedToProvisioningNetwork = false;
}
/** {@hide} */
@@ -160,7 +158,6 @@
mIsFailover = source.mIsFailover;
mIsRoaming = source.mIsRoaming;
mIsAvailable = source.mIsAvailable;
- mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
}
}
}
@@ -332,22 +329,6 @@
}
}
- /** {@hide} */
- @VisibleForTesting
- public boolean isConnectedToProvisioningNetwork() {
- synchronized (this) {
- return mIsConnectedToProvisioningNetwork;
- }
- }
-
- /** {@hide} */
- @VisibleForTesting
- public void setIsConnectedToProvisioningNetwork(boolean val) {
- synchronized (this) {
- mIsConnectedToProvisioningNetwork = val;
- }
- }
-
/**
* Reports the current coarse-grained state of the network.
* @return the coarse-grained state
@@ -431,8 +412,6 @@
append(", roaming: ").append(mIsRoaming).
append(", failover: ").append(mIsFailover).
append(", isAvailable: ").append(mIsAvailable).
- append(", isConnectedToProvisioningNetwork: ").
- append(mIsConnectedToProvisioningNetwork).
append("]");
return builder.toString();
}
@@ -461,7 +440,6 @@
dest.writeInt(mIsFailover ? 1 : 0);
dest.writeInt(mIsAvailable ? 1 : 0);
dest.writeInt(mIsRoaming ? 1 : 0);
- dest.writeInt(mIsConnectedToProvisioningNetwork ? 1 : 0);
dest.writeString(mReason);
dest.writeString(mExtraInfo);
}
@@ -484,7 +462,6 @@
netInfo.mIsFailover = in.readInt() != 0;
netInfo.mIsAvailable = in.readInt() != 0;
netInfo.mIsRoaming = in.readInt() != 0;
- netInfo.mIsConnectedToProvisioningNetwork = in.readInt() != 0;
netInfo.mReason = in.readString();
netInfo.mExtraInfo = in.readString();
return netInfo;
diff --git a/core/tests/coretests/src/android/net/NetworkTest.java b/core/tests/coretests/src/android/net/NetworkTest.java
index b0ecb04..74b6d98 100644
--- a/core/tests/coretests/src/android/net/NetworkTest.java
+++ b/core/tests/coretests/src/android/net/NetworkTest.java
@@ -16,11 +16,14 @@
package android.net;
+import static android.test.MoreAsserts.assertNotEqual;
+
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.net.Network;
import android.test.suitebuilder.annotation.SmallTest;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -29,6 +32,7 @@
import java.net.InetAddress;
import java.net.Inet6Address;
import java.net.SocketException;
+
import junit.framework.TestCase;
public class NetworkTest extends TestCase {
@@ -93,4 +97,50 @@
fail("SocketException not thrown");
} catch (SocketException expected) {}
}
+
+ @SmallTest
+ public void testZeroIsObviousForDebugging() {
+ Network zero = new Network(0);
+ assertEquals(0, zero.hashCode());
+ assertEquals(0, zero.getNetworkHandle());
+ assertEquals("0", zero.toString());
+ }
+
+ @SmallTest
+ public void testGetNetworkHandle() {
+ Network one = new Network(1);
+ Network two = new Network(2);
+ Network three = new Network(3);
+
+ // None of the hashcodes are zero.
+ assertNotEqual(0, one.hashCode());
+ assertNotEqual(0, two.hashCode());
+ assertNotEqual(0, three.hashCode());
+
+ // All the hashcodes are distinct.
+ assertNotEqual(one.hashCode(), two.hashCode());
+ assertNotEqual(one.hashCode(), three.hashCode());
+ assertNotEqual(two.hashCode(), three.hashCode());
+
+ // None of the handles are zero.
+ assertNotEqual(0, one.getNetworkHandle());
+ assertNotEqual(0, two.getNetworkHandle());
+ assertNotEqual(0, three.getNetworkHandle());
+
+ // All the handles are distinct.
+ assertNotEqual(one.getNetworkHandle(), two.getNetworkHandle());
+ assertNotEqual(one.getNetworkHandle(), three.getNetworkHandle());
+ assertNotEqual(two.getNetworkHandle(), three.getNetworkHandle());
+
+ // The handles are not equal to the hashcodes.
+ assertNotEqual(one.hashCode(), one.getNetworkHandle());
+ assertNotEqual(two.hashCode(), two.getNetworkHandle());
+ assertNotEqual(three.hashCode(), three.getNetworkHandle());
+
+ // Adjust as necessary to test an implementation's specific constants.
+ // When running with runtest, "adb logcat -s TestRunner" can be useful.
+ assertEquals(4311403230L, one.getNetworkHandle());
+ assertEquals(8606370526L, two.getNetworkHandle());
+ assertEquals(12901337822L, three.getNetworkHandle());
+ }
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 00d7a50..08b7184 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -136,11 +136,13 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -960,44 +962,6 @@
return nai != null ? nai.network : null;
}
- /**
- * Find the first Provisioning network.
- *
- * @return NetworkInfo or null if none.
- */
- private NetworkInfo getProvisioningNetworkInfo() {
- enforceAccessPermission();
-
- // Find the first Provisioning Network
- NetworkInfo provNi = null;
- for (NetworkInfo ni : getAllNetworkInfo()) {
- if (ni.isConnectedToProvisioningNetwork()) {
- provNi = ni;
- break;
- }
- }
- if (DBG) log("getProvisioningNetworkInfo: X provNi=" + provNi);
- return provNi;
- }
-
- /**
- * Find the first Provisioning network or the ActiveDefaultNetwork
- * if there is no Provisioning network
- *
- * @return NetworkInfo or null if none.
- */
- @Override
- public NetworkInfo getProvisioningOrActiveNetworkInfo() {
- enforceAccessPermission();
-
- NetworkInfo provNi = getProvisioningNetworkInfo();
- if (provNi == null) {
- provNi = getActiveNetworkInfo();
- }
- if (DBG) log("getProvisioningOrActiveNetworkInfo: X provNi=" + provNi);
- return provNi;
- }
-
public NetworkInfo getActiveNetworkInfoUnfiltered() {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
@@ -1567,14 +1531,6 @@
}
};
- /** @hide */
- @Override
- public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
- enforceConnectivityInternalPermission();
- if (DBG) log("captivePortalCheckCompleted: ni=" + info + " captive=" + isCaptivePortal);
-// mNetTrackers[info.getType()].captivePortalCheckCompleted(isCaptivePortal);
- }
-
/**
* Setup data activity tracking for the given network.
*
@@ -3293,7 +3249,6 @@
CharSequence title;
CharSequence details;
int icon;
- Notification notification = new Notification();
if (notifyType == NotificationType.NO_INTERNET &&
networkType == ConnectivityManager.TYPE_WIFI) {
title = r.getString(R.string.wifi_no_internet, 0);
@@ -3328,14 +3283,17 @@
return;
}
- notification.when = 0;
- notification.icon = icon;
- notification.flags = Notification.FLAG_AUTO_CANCEL;
- notification.tickerText = title;
- notification.color = mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color);
- notification.setLatestEventInfo(mContext, title, details, notification.contentIntent);
- notification.contentIntent = intent;
+ Notification notification = new Notification.Builder(mContext)
+ .setWhen(0)
+ .setSmallIcon(icon)
+ .setAutoCancel(true)
+ .setTicker(title)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(details)
+ .setContentIntent(intent)
+ .build();
try {
notificationManager.notify(NOTIFICATION_ID, id, notification);
@@ -3359,7 +3317,6 @@
* <?xml version="1.0" encoding="utf-8"?>
* <provisioningUrls>
* <provisioningUrl mcc="310" mnc="4">http://myserver.com/foo?mdn=%3$s&iccid=%1$s&imei=%2$s</provisioningUrl>
- * <redirectedUrl mcc="310" mnc="4">http://www.google.com</redirectedUrl>
* </provisioningUrls>
*/
private static final String PROVISIONING_URL_PATH =
@@ -3370,33 +3327,15 @@
private static final String TAG_PROVISIONING_URLS = "provisioningUrls";
/** XML tag for individual url */
private static final String TAG_PROVISIONING_URL = "provisioningUrl";
- /** XML tag for redirected url */
- private static final String TAG_REDIRECTED_URL = "redirectedUrl";
/** XML attribute for mcc */
private static final String ATTR_MCC = "mcc";
/** XML attribute for mnc */
private static final String ATTR_MNC = "mnc";
- private static final int REDIRECTED_PROVISIONING = 1;
- private static final int PROVISIONING = 2;
-
- private String getProvisioningUrlBaseFromFile(int type) {
+ private String getProvisioningUrlBaseFromFile() {
FileReader fileReader = null;
XmlPullParser parser = null;
Configuration config = mContext.getResources().getConfiguration();
- String tagType;
-
- switch (type) {
- case PROVISIONING:
- tagType = TAG_PROVISIONING_URL;
- break;
- case REDIRECTED_PROVISIONING:
- tagType = TAG_REDIRECTED_URL;
- break;
- default:
- throw new RuntimeException("getProvisioningUrlBaseFromFile: Unexpected parameter " +
- type);
- }
try {
fileReader = new FileReader(mProvisioningUrlFile);
@@ -3410,7 +3349,7 @@
String element = parser.getName();
if (element == null) break;
- if (element.equals(tagType)) {
+ if (element.equals(TAG_PROVISIONING_URL)) {
String mcc = parser.getAttributeValue(null, ATTR_MCC);
try {
if (mcc != null && Integer.parseInt(mcc) == config.mcc) {
@@ -3445,19 +3384,9 @@
}
@Override
- public String getMobileRedirectedProvisioningUrl() {
- enforceConnectivityInternalPermission();
- String url = getProvisioningUrlBaseFromFile(REDIRECTED_PROVISIONING);
- if (TextUtils.isEmpty(url)) {
- url = mContext.getResources().getString(R.string.mobile_redirected_provisioning_url);
- }
- return url;
- }
-
- @Override
public String getMobileProvisioningUrl() {
enforceConnectivityInternalPermission();
- String url = getProvisioningUrlBaseFromFile(PROVISIONING);
+ String url = getProvisioningUrlBaseFromFile();
if (TextUtils.isEmpty(url)) {
url = mContext.getResources().getString(R.string.mobile_provisioning_url);
log("getMobileProvisioningUrl: mobile_provisioining_url from resource =" + url);
@@ -3997,10 +3926,52 @@
}
return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty();
}
+
+ // TODO: investigate moving this into LinkProperties, if only to make more accurate
+ // the isProvisioned() checks.
+ private static Collection<InetAddress> getLikelyReachableDnsServers(LinkProperties lp) {
+ final ArrayList<InetAddress> dnsServers = new ArrayList<InetAddress>();
+ final List<RouteInfo> allRoutes = lp.getAllRoutes();
+ for (InetAddress nameserver : lp.getDnsServers()) {
+ // If the LinkProperties doesn't include a route to the nameserver, ignore it.
+ final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, nameserver);
+ if (bestRoute == null) {
+ continue;
+ }
+
+ // TODO: better source address evaluation for destination addresses.
+ if (nameserver instanceof Inet4Address) {
+ if (!lp.hasIPv4Address()) {
+ continue;
+ }
+ } else if (nameserver instanceof Inet6Address) {
+ if (nameserver.isLinkLocalAddress()) {
+ if (((Inet6Address)nameserver).getScopeId() == 0) {
+ // For now, just make sure link-local DNS servers have
+ // scopedIds set, since DNS lookups will fail otherwise.
+ // TODO: verify the scopeId matches that of lp's interface.
+ continue;
+ }
+ } else {
+ if (bestRoute.isIPv6Default() && !lp.hasGlobalIPv6Address()) {
+ // TODO: reconsider all corner cases (disconnected ULA networks, ...).
+ continue;
+ }
+ }
+ }
+
+ dnsServers.add(nameserver);
+ }
+ return Collections.unmodifiableList(dnsServers);
+ }
+
private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId,
boolean flush, boolean useDefaultDns) {
+ // TODO: consider comparing the getLikelyReachableDnsServers() lists, in case the
+ // route to a DNS server has been removed (only really applicable in special cases
+ // where there is no default route).
if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) {
- Collection<InetAddress> dnses = newLp.getDnsServers();
+ Collection<InetAddress> dnses = getLikelyReachableDnsServers(newLp);
if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) {
dnses = new ArrayList();
dnses.add(mDefaultDns);