Merge "Fix reference to ProxyInfo extra"
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a414421..1837335 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -21,6 +21,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
 import android.os.Handler;
@@ -57,13 +58,15 @@
  * is lost</li>
  * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
  * state of the available networks</li>
+ * <li>Provide an API that allows applications to request and select networks for their data
+ * traffic</li>
  * </ol>
  */
 public class ConnectivityManager {
     private static final String TAG = "ConnectivityManager";
 
     /**
-     * A change in network connectivity has occurred. A connection has either
+     * A change in network connectivity has occurred. A default connection has either
      * been established or lost. The NetworkInfo for the affected network is
      * sent as an extra; it should be consulted to see what kind of
      * connectivity event occurred.
@@ -547,13 +550,12 @@
      * @param preference the network type to prefer over all others.  It is
      *         unspecified what happens to the old preferred network in the
      *         overall ordering.
+     * @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
+     *             the networks to describe their precedence.
      */
     public void setNetworkPreference(int preference) {
-        // TODO - deprecate with:
-        // @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
-        //         the networks to describe their precedence.
     }
 
     /**
@@ -563,14 +565,13 @@
      *
      * <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
+     *             the networks to describe their precedence.
      */
     public int getNetworkPreference() {
-        // TODO - deprecate with:
-        // @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
-        //         the networks to describe their precedence.
-        return -1;
+        return TYPE_NONE;
     }
 
     /**
@@ -716,7 +717,13 @@
         }
     }
 
-    /** {@hide} */
+    /**
+     * Get the {@link LinkProperties} for the given {@link Network}.  This
+     * will return {@code null} if the network is unknown.
+     *
+     * @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);
@@ -725,7 +732,13 @@
         }
     }
 
-    /** {@hide} */
+    /**
+     * Get the {@link NetworkCapabilities} for the given {@link Network}.  This
+     * will return {@code null} if the network is unknown.
+     *
+     * @param network The {@link Network} object identifying the network in question.
+     * @return The {@link NetworkCapabilities} for the network, or {@code null}.
+     */
     public NetworkCapabilities getNetworkCapabilities(Network network) {
         try {
             return mService.getNetworkCapabilities(network);
@@ -788,6 +801,8 @@
      * The interpretation of this value is specific to each networking
      * implementation+feature combination, except that the value {@code -1}
      * always indicates failure.
+     *
+     * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
      */
     public int startUsingNetworkFeature(int networkType, String feature) {
         try {
@@ -810,6 +825,8 @@
      * The interpretation of this value is specific to each networking
      * implementation+feature combination, except that the value {@code -1}
      * always indicates failure.
+     *
+     * @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
      */
     public int stopUsingNetworkFeature(int networkType, String feature) {
         try {
@@ -829,6 +846,9 @@
      * host is to be routed
      * @param hostAddress the IP address of the host to which the route is desired
      * @return {@code true} on success, {@code false} on failure
+     *
+     * @deprecated Deprecated in favor of the {@link #requestNetwork},
+     *             {@link Network#bindProcess} and {@link Network#socketFactory} api.
      */
     public boolean requestRouteToHost(int networkType, int hostAddress) {
         InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress);
@@ -851,6 +871,8 @@
      * @param hostAddress the IP address of the host to which the route is desired
      * @return {@code true} on success, {@code false} on failure
      * @hide
+     * @deprecated Deprecated in favor of the {@link #requestNetwork} and
+     *             {@link Network#bindProcess} api.
      */
     public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
         byte[] address = hostAddress.getAddress();
@@ -1332,13 +1354,13 @@
     }
 
     /**
-     * Report a problem network to the framework.  This will cause the framework
-     * to evaluate the situation and try to fix any problems.  Note that false
-     * may be subsequently ignored.
+     * Report a problem network to the framework.  This provides a hint to the system
+     * that there might be connectivity problems on this network and may cause 
+     * the framework to re-evaluate network connectivity and/or switch to another
+     * network.
      *
-     * @param network The Network the application was attempting to use or null
-     *                to indicate the current default network.
-     * {@hide}
+     * @param network The {@link Network} the application was attempting to use
+     *                or {@code null} to indicate the current default network.
      */
     public void reportBadNetwork(Network network) {
         try {
@@ -1358,6 +1380,7 @@
      *
      * <p>This method requires the call to hold the permission
      * android.Manifest.permission#CONNECTIVITY_INTERNAL.
+     * @hide
      */
     public void setGlobalProxy(ProxyInfo p) {
         try {
@@ -1374,6 +1397,7 @@
      *
      * <p>This method requires the call to hold the permission
      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+     * @hide
      */
     public ProxyInfo getGlobalProxy() {
         try {
@@ -1393,6 +1417,7 @@
      * <p>This method requires the call to hold the permission
      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
      * {@hide}
+     * @deprecated Deprecated in favor of {@link #getLinkProperties}
      */
     public ProxyInfo getProxy() {
         try {
@@ -1645,11 +1670,10 @@
     }
 
     /**
-     * Interface for NetworkRequest callbacks.  Used for notifications about network
-     * changes.
-     * @hide
+     * Base class for NetworkRequest callbacks.  Used for notifications about network
+     * changes.  Should be extended by applications wanting notifications.
      */
-    public static class NetworkCallbacks {
+    public static class NetworkCallbackListener {
         /** @hide */
         public static final int PRECHECK     = 1;
         /** @hide */
@@ -1675,51 +1699,73 @@
         public void onPreCheck(NetworkRequest networkRequest, Network network) {}
 
         /**
-         * Called when the framework connects and has validated the new network.
+         * Called when the framework connects and has declared new network ready for use.
+         *
+         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
+         * @param network The {@link Network} of the satisfying network.
          */
         public void onAvailable(NetworkRequest networkRequest, Network network) {}
 
         /**
-         * Called when the framework is losing the network.  Often paired with an
-         * onAvailable call with the new replacement network for graceful handover.
-         * This may not be called if we have a hard loss (loss without warning).
-         * This may be followed by either an onLost call or an onAvailable call for this
-         * network depending on if we lose or regain it.
+         * Called when the network is about to be disconnected.  Often paired with an
+         * {@link NetworkCallbackListener#onAvailable} call with the new replacement network
+         * for graceful handover.  This may not be called if we have a hard loss
+         * (loss without warning).  This may be followed by either a
+         * {@link NetworkCallbackListener#onLost} call or a
+         * {@link NetworkCallbackListener#onAvailable} call for this network depending
+         * on whether we lose or regain it.
+         *
+         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
+         * @param network The {@link Network} of the failing network.
+         * @param maxSecToLive The time in seconds the framework will attempt to keep the
+         *                     network connected.  Note that the network may suffers a
+         *                     hard loss at any time.
          */
         public void onLosing(NetworkRequest networkRequest, Network network, int maxSecToLive) {}
 
         /**
          * Called when the framework has a hard loss of the network or when the
-         * graceful failure ends.  Note applications should only request this callback
-         * if the application is willing to track the Available and Lost callbacks
-         * together, else the application may think it has no network when it
-         * really does (A Avail, B Avail, A Lost..  still have B).
+         * graceful failure ends.
+         *
+         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
+         * @param network The {@link Network} lost.
          */
         public void onLost(NetworkRequest networkRequest, Network network) {}
 
         /**
          * Called if no network is found in the given timeout time.  If no timeout is given,
          * this will not be called.
+         * @hide
          */
         public void onUnavailable(NetworkRequest networkRequest) {}
 
         /**
          * Called when the network the framework connected to for this request
          * changes capabilities but still satisfies the stated need.
+         *
+         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
+         * @param network The {@link Network} whose capabilities have changed.
+         * @param networkCapabilities The new {@link NetworkCapabilities} for this network.
          */
         public void onNetworkCapabilitiesChanged(NetworkRequest networkRequest, Network network,
                 NetworkCapabilities networkCapabilities) {}
 
         /**
          * Called when the network the framework connected to for this request
-         * changes LinkProperties.
+         * changes {@link LinkProperties}.
+         *
+         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
+         * @param network The {@link Network} whose link properties have changed.
+         * @param linkProperties The new {@link LinkProperties} for this network.
          */
         public void onLinkPropertiesChanged(NetworkRequest networkRequest, Network network,
                 LinkProperties linkProperties) {}
 
         /**
-         * Called when a releaseNetworkRequest call concludes and the registered callbacks will
-         * no longer be used.
+         * Called when a {@link #releaseNetworkRequest} call concludes and the registered
+         * callbacks will no longer be used.
+         *
+         * @param networkRequest The {@link NetworkRequest} used to initiate the request.
          */
         public void onReleased(NetworkRequest networkRequest) {}
     }
@@ -1745,12 +1791,12 @@
     public static final int CALLBACK_EXIT               = BASE + 9;
 
     private static class CallbackHandler extends Handler {
-        private final HashMap<NetworkRequest, NetworkCallbacks>mCallbackMap;
+        private final HashMap<NetworkRequest, NetworkCallbackListener>mCallbackMap;
         private final AtomicInteger mRefCount;
         private static final String TAG = "ConnectivityManager.CallbackHandler";
         private final ConnectivityManager mCm;
 
-        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallbacks>callbackMap,
+        CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallbackListener>callbackMap,
                 AtomicInteger refCount, ConnectivityManager cm) {
             super(looper);
             mCallbackMap = callbackMap;
@@ -1764,7 +1810,7 @@
             switch (message.what) {
                 case CALLBACK_PRECHECK: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbacks callbacks = getCallbacks(request);
+                    NetworkCallbackListener callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         callbacks.onPreCheck(request, getNetwork(message));
                     } else {
@@ -1774,7 +1820,7 @@
                 }
                 case CALLBACK_AVAILABLE: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbacks callbacks = getCallbacks(request);
+                    NetworkCallbackListener callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         callbacks.onAvailable(request, getNetwork(message));
                     } else {
@@ -1784,7 +1830,7 @@
                 }
                 case CALLBACK_LOSING: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbacks callbacks = getCallbacks(request);
+                    NetworkCallbackListener callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         callbacks.onLosing(request, getNetwork(message), message.arg1);
                     } else {
@@ -1794,7 +1840,7 @@
                 }
                 case CALLBACK_LOST: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbacks callbacks = getCallbacks(request);
+                    NetworkCallbackListener callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         callbacks.onLost(request, getNetwork(message));
                     } else {
@@ -1804,7 +1850,7 @@
                 }
                 case CALLBACK_UNAVAIL: {
                     NetworkRequest req = (NetworkRequest)message.obj;
-                    NetworkCallbacks callbacks = null;
+                    NetworkCallbackListener callbacks = null;
                     synchronized(mCallbackMap) {
                         callbacks = mCallbackMap.get(req);
                     }
@@ -1817,7 +1863,7 @@
                 }
                 case CALLBACK_CAP_CHANGED: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbacks callbacks = getCallbacks(request);
+                    NetworkCallbackListener callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         Network network = getNetwork(message);
                         NetworkCapabilities cap = mCm.getNetworkCapabilities(network);
@@ -1830,7 +1876,7 @@
                 }
                 case CALLBACK_IP_CHANGED: {
                     NetworkRequest request = getNetworkRequest(message);
-                    NetworkCallbacks callbacks = getCallbacks(request);
+                    NetworkCallbackListener callbacks = getCallbacks(request);
                     if (callbacks != null) {
                         Network network = getNetwork(message);
                         LinkProperties lp = mCm.getLinkProperties(network);
@@ -1843,7 +1889,7 @@
                 }
                 case CALLBACK_RELEASED: {
                     NetworkRequest req = (NetworkRequest)message.obj;
-                    NetworkCallbacks callbacks = null;
+                    NetworkCallbackListener callbacks = null;
                     synchronized(mCallbackMap) {
                         callbacks = mCallbackMap.remove(req);
                     }
@@ -1870,7 +1916,7 @@
         private NetworkRequest getNetworkRequest(Message msg) {
             return (NetworkRequest)(msg.obj);
         }
-        private NetworkCallbacks getCallbacks(NetworkRequest req) {
+        private NetworkCallbackListener getCallbacks(NetworkRequest req) {
             synchronized(mCallbackMap) {
                 return mCallbackMap.get(req);
             }
@@ -1878,7 +1924,7 @@
         private Network getNetwork(Message msg) {
             return new Network(msg.arg2);
         }
-        private NetworkCallbacks removeCallbacks(Message msg) {
+        private NetworkCallbackListener removeCallbacks(Message msg) {
             NetworkRequest req = (NetworkRequest)msg.obj;
             synchronized(mCallbackMap) {
                 return mCallbackMap.remove(req);
@@ -1893,7 +1939,7 @@
                 HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
                 callbackThread.start();
                 sCallbackHandler = new CallbackHandler(callbackThread.getLooper(),
-                        sNetworkCallbacks, sCallbackRefCount, this);
+                        sNetworkCallbackListener, sCallbackRefCount, this);
             }
         }
     }
@@ -1907,8 +1953,8 @@
         }
     }
 
-    static final HashMap<NetworkRequest, NetworkCallbacks> sNetworkCallbacks =
-            new HashMap<NetworkRequest, NetworkCallbacks>();
+    static final HashMap<NetworkRequest, NetworkCallbackListener> sNetworkCallbackListener =
+            new HashMap<NetworkRequest, NetworkCallbackListener>();
     static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
     static CallbackHandler sCallbackHandler = null;
 
@@ -1916,9 +1962,11 @@
     private final static int REQUEST = 2;
 
     private NetworkRequest somethingForNetwork(NetworkCapabilities need,
-            NetworkCallbacks networkCallbacks, int timeoutSec, int action) {
+            NetworkCallbackListener networkCallbackListener, int timeoutSec, int action) {
         NetworkRequest networkRequest = null;
-        if (networkCallbacks == null) throw new IllegalArgumentException("null NetworkCallbacks");
+        if (networkCallbackListener == null) {
+            throw new IllegalArgumentException("null NetworkCallbackListener");
+        }
         if (need == null) throw new IllegalArgumentException("null NetworkCapabilities");
         try {
             addCallbackListener();
@@ -1930,8 +1978,8 @@
                         timeoutSec, new Binder());
             }
             if (networkRequest != null) {
-                synchronized(sNetworkCallbacks) {
-                    sNetworkCallbacks.put(networkRequest, networkCallbacks);
+                synchronized(sNetworkCallbackListener) {
+                    sNetworkCallbackListener.put(networkRequest, networkCallbackListener);
                 }
             }
         } catch (RemoteException e) {}
@@ -1943,46 +1991,44 @@
      * Request a network to satisfy a set of {@link NetworkCapabilities}.
      *
      * This {@link NetworkRequest} will live until released via
-     * {@link releaseNetworkRequest} or the calling application exits.
-     * Status of the request can be follwed by listening to the various
-     * callbacks described in {@link NetworkCallbacks}.  The {@link Network}
-     * can be used by using the {@link bindSocketToNetwork},
-     * {@link bindApplicationToNetwork} and {@link getAddrInfoOnNetwork} functions.
+     * {@link #releaseNetworkRequest} or the calling application exits.
+     * Status of the request can be followed by listening to the various
+     * callbacks described in {@link NetworkCallbackListener}.  The {@link Network}
+     * can be used to direct traffic to the network.
      *
      * @param need {@link NetworkCapabilities} required by this request.
-     * @param networkCallbacks The callbacks to be utilized for this request.  Note
-     *                         the callbacks can be shared by multiple requests and
-     *                         the NetworkRequest token utilized to determine to which
-     *                         request the callback relates.
+     * @param networkCallbackListener The {@link NetworkCallbackListener} to be utilized for this
+     *                         request.  Note the callbacks can be shared by multiple
+     *                         requests and the NetworkRequest token utilized to
+     *                         determine to which request the callback relates.
      * @return A {@link NetworkRequest} object identifying the request.
-     * @hide
      */
     public NetworkRequest requestNetwork(NetworkCapabilities need,
-            NetworkCallbacks networkCallbacks) {
-        return somethingForNetwork(need, networkCallbacks, 0, REQUEST);
+            NetworkCallbackListener networkCallbackListener) {
+        return somethingForNetwork(need, networkCallbackListener, 0, REQUEST);
     }
 
     /**
      * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
      * by a timeout.
      *
-     * This function behaves identically, but if a suitable network is not found
-     * within the given time (in Seconds) the {@link NetworkCallbacks#unavailable}
-     * callback is called.  The request must still be released normally by
-     * calling {@link releaseNetworkRequest}.
+     * This function behaves identically to the non-timedout version, but if a suitable
+     * network is not found within the given time (in Seconds) the
+     * {@link NetworkCallbackListener#unavailable} callback is called.  The request must
+     * still be released normally by calling {@link releaseNetworkRequest}.
      * @param need {@link NetworkCapabilities} required by this request.
-     * @param networkCallbacks The callbacks to be utilized for this request.  Note
+     * @param networkCallbackListener The callbacks to be utilized for this request.  Note
      *                         the callbacks can be shared by multiple requests and
      *                         the NetworkRequest token utilized to determine to which
      *                         request the callback relates.
      * @param timeoutSec The time in seconds to attempt looking for a suitable network
-     *                   before {@link NetworkCallbacks#unavailable} is called.
+     *                   before {@link NetworkCallbackListener#unavailable} is called.
      * @return A {@link NetworkRequest} object identifying the request.
      * @hide
      */
     public NetworkRequest requestNetwork(NetworkCapabilities need,
-            NetworkCallbacks networkCallbacks, int timeoutSec) {
-        return somethingForNetwork(need, networkCallbacks, timeoutSec, REQUEST);
+            NetworkCallbackListener networkCallbackListener, int timeoutSec) {
+        return somethingForNetwork(need, networkCallbackListener, timeoutSec, REQUEST);
     }
 
     /**
@@ -1993,36 +2039,52 @@
     public final static int MAX_NETWORK_REQUEST_TIMEOUT_SEC = 100 * 60;
 
     /**
+     * The lookup key for a {@link Network} object included with the intent after
+     * succesfully finding a network for the applications request.  Retrieve it with
+     * {@link android.content.Intent#getParcelableExtra(String)}.
+     */
+    public static final String EXTRA_NETWORK_REQUEST_NETWORK = "networkRequestNetwork";
+
+    /**
+     * The lookup key for a {@link NetworkCapabilities} object included with the intent after
+     * succesfully finding a network for the applications request.  Retrieve it with
+     * {@link android.content.Intent#getParcelableExtra(String)}.
+     */
+    public static final String EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES =
+            "networkRequestNetworkCapabilities";
+
+
+    /**
      * Request a network to satisfy a set of {@link NetworkCapabilities}.
      *
-     * This function behavies identically, but instead of {@link NetworkCallbacks}
-     * a {@link PendingIntent} is used.  This means the request may outlive the
-     * calling application and get called back when a suitable network is found.
+     * This function behavies identically to the callback-equiped version, but instead
+     * of {@link NetworkCallbackListener} a {@link PendingIntent} is used.  This means
+     * the request may outlive the calling application and get called back when a suitable
+     * network is found.
      * <p>
      * The operation is an Intent broadcast that goes to a broadcast receiver that
      * you registered with {@link Context#registerReceiver} or through the
      * &lt;receiver&gt; tag in an AndroidManifest.xml file
      * <p>
      * The operation Intent is delivered with two extras, a {@link Network} typed
-     * extra called {@link EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkCapabilities}
-     * typed extra called {@link EXTRA_NETWORK_REQUEST_NETWORK_CAPABILTIES} containing
+     * extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkCapabilities}
+     * typed extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES} containing
      * the original requests parameters.  It is important to create a new,
-     * {@link NetworkCallbacks} based request before completing the processing of the
+     * {@link NetworkCallbackListener} based request before completing the processing of the
      * Intent to reserve the network or it will be released shortly after the Intent
      * is processed.
      * <p>
      * If there is already an request for this Intent registered (with the equality of
      * two Intents defined by {@link Intent#filterEquals}), then it will be removed and
-     * replace by this one, effectively releasing the previous {@link NetworkRequest}.
+     * replaced by this one, effectively releasing the previous {@link NetworkRequest}.
      * <p>
-     * The request may be released normally by calling {@link releaseNetworkRequest}.
+     * The request may be released normally by calling {@link #releaseNetworkRequest}.
      *
-     * @param need {@link NetworkCapabilties} required by this request.
+     * @param need {@link NetworkCapabilities} required by this request.
      * @param operation Action to perform when the network is available (corresponds
-     *                  to the {@link NetworkCallbacks#onAvailable} call.  Typically
+     *                  to the {@link NetworkCallbackListener#onAvailable} call.  Typically
      *                  comes from {@link PendingIntent#getBroadcast}.
      * @return A {@link NetworkRequest} object identifying the request.
-     * @hide
      */
     public NetworkRequest requestNetwork(NetworkCapabilities need, PendingIntent operation) {
         try {
@@ -2035,28 +2097,27 @@
      * Registers to receive notifications about all networks which satisfy the given
      * {@link NetworkCapabilities}.  The callbacks will continue to be called until
      * either the application exits or the request is released using
-     * {@link releaseNetworkRequest}.
+     * {@link #releaseNetworkRequest}.
      *
      * @param need {@link NetworkCapabilities} required by this request.
-     * @param networkCallbacks The {@link NetworkCallbacks} to be called as suitable
+     * @param networkCallbackListener The {@link NetworkCallbackListener} to be called as suitable
      *                         networks change state.
      * @return A {@link NetworkRequest} object identifying the request.
-     * @hide
      */
     public NetworkRequest listenForNetwork(NetworkCapabilities need,
-            NetworkCallbacks networkCallbacks) {
-        return somethingForNetwork(need, networkCallbacks, 0, LISTEN);
+            NetworkCallbackListener networkCallbackListener) {
+        return somethingForNetwork(need, networkCallbackListener, 0, LISTEN);
     }
 
     /**
-     * Releases a {NetworkRequest} generated either through a {@link requestNetwork}
-     * or a {@link listenForNetwork} call.  The {@link NetworkCallbacks} given in the
-     * earlier call may continue receiving calls until the {@link NetworkCallbacks#onReleased}
-     * function is called, signifiying the end of the request.
+     * Releases a {@link NetworkRequest} generated either through a {@link #requestNetwork}
+     * or a {@link #listenForNetwork} call.  The {@link NetworkCallbackListener} given in the
+     * earlier call may continue receiving calls until the
+     * {@link NetworkCallbackListener#onReleased} function is called, signifying the end
+     * of the request.
      *
      * @param networkRequest The {@link NetworkRequest} generated by an earlier call to
-     *                       {@link requestNetwork} or {@link listenForNetwork}.
-     * @hide
+     *                       {@link #requestNetwork} or {@link #listenForNetwork}.
      */
     public void releaseNetworkRequest(NetworkRequest networkRequest) {
         if (networkRequest == null) throw new IllegalArgumentException("null NetworkRequest");
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index a725bec..d07c0b6 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -39,7 +39,8 @@
  * <ul>
  * <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}).
  * The address must be unicast, as multicast addresses cannot be assigned to interfaces.
- * <li>Address flags: A bitmask of {@code IFA_F_*} values representing properties of the address.
+ * <li>Address flags: A bitmask of {@code IFA_F_*} values representing properties
+ * of the address.
  * <li>Address scope: An integer defining the scope in which the address is unique (e.g.,
  * {@code RT_SCOPE_LINK} or {@code RT_SCOPE_SITE}).
  * <ul>
@@ -47,10 +48,9 @@
  * When constructing a {@code LinkAddress}, the IP address and prefix are required. The flags and
  * scope are optional. If they are not specified, the flags are set to zero, and the scope will be
  * determined based on the IP address (e.g., link-local addresses will be created with a scope of
- * {@code RT_SCOPE_LINK}, global addresses with {@code RT_SCOPE_UNIVERSE}, etc.) If they are
- * specified, they are not checked for validity.
+ * {@code RT_SCOPE_LINK}, global addresses with {@code RT_SCOPE_UNIVERSE},
+ * etc.) If they are specified, they are not checked for validity.
  *
- * @hide
  */
 public class LinkAddress implements Parcelable {
     /**
@@ -119,6 +119,10 @@
      * the specified flags and scope. Flags and scope are not checked for validity.
      * @param address The IP address.
      * @param prefixLength The prefix length.
+     * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
+     * @param scope An integer defining the scope in which the address is unique (e.g.,
+     *              {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
+     * @hide
      */
     public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) {
         init(address, prefixLength, flags, scope);
@@ -129,6 +133,7 @@
      * The flags are set to zero and the scope is determined from the address.
      * @param address The IP address.
      * @param prefixLength The prefix length.
+     * @hide
      */
     public LinkAddress(InetAddress address, int prefixLength) {
         this(address, prefixLength, 0, 0);
@@ -139,6 +144,7 @@
      * Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}.
      * The flags are set to zero and the scope is determined from the address.
      * @param interfaceAddress The interface address.
+     * @hide
      */
     public LinkAddress(InterfaceAddress interfaceAddress) {
         this(interfaceAddress.getAddress(),
@@ -149,6 +155,7 @@
      * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
      * "2001:db8::1/64". The flags are set to zero and the scope is determined from the address.
      * @param string The string to parse.
+     * @hide
      */
     public LinkAddress(String address) {
         this(address, 0, 0);
@@ -161,6 +168,7 @@
      * @param string The string to parse.
      * @param flags The address flags.
      * @param scope The address scope.
+     * @hide
      */
     public LinkAddress(String address, int flags, int scope) {
         InetAddress inetAddress = null;
@@ -220,9 +228,10 @@
     }
 
     /**
-     * Determines whether this {@code LinkAddress} and the provided {@code LinkAddress} represent
-     * the same address. Two LinkAddresses represent the same address if they have the same IP
-     * address and prefix length, even if their properties are different.
+     * Determines whether this {@code LinkAddress} and the provided {@code LinkAddress}
+     * represent the same address. Two {@code LinkAddresses} represent the same address
+     * if they have the same IP address and prefix length, even if their properties are
+     * different.
      *
      * @param other the {@code LinkAddress} to compare to.
      * @return {@code true} if both objects have the same address and prefix length, {@code false}
@@ -233,28 +242,28 @@
     }
 
     /**
-     * Returns the InetAddress of this address.
+     * Returns the {@link InetAddress} of this {@code LinkAddress}.
      */
     public InetAddress getAddress() {
         return address;
     }
 
     /**
-     * Returns the prefix length of this address.
+     * Returns the prefix length of this {@code LinkAddress}.
      */
     public int getNetworkPrefixLength() {
         return prefixLength;
     }
 
     /**
-     * Returns the flags of this address.
+     * Returns the flags of this {@code LinkAddress}.
      */
     public int getFlags() {
         return flags;
     }
 
     /**
-     * Returns the scope of this address.
+     * Returns the scope of this {@code LinkAddress}.
      */
     public int getScope() {
         return scope;
@@ -262,6 +271,7 @@
 
     /**
      * Returns true if this {@code LinkAddress} is global scope and preferred.
+     * @hide
      */
     public boolean isGlobalPreferred() {
         return (scope == RT_SCOPE_UNIVERSE &&
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 0a09fcb..3c36679 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -36,27 +36,12 @@
  *
  * A link represents a connection to a network.
  * It may have multiple addresses and multiple gateways,
- * multiple dns servers but only one http proxy.
+ * multiple dns servers but only one http proxy and one
+ * network interface.
  *
- * Because it's a single network, the dns's
- * are interchangeable and don't need associating with
- * particular addresses.  The gateways similarly don't
- * need associating with particular addresses.
+ * Note that this is just a holder of data.  Modifying it
+ * does not affect live networks.
  *
- * A dual stack interface works fine in this model:
- * each address has it's own prefix length to describe
- * the local network.  The dns servers all return
- * both v4 addresses and v6 addresses regardless of the
- * address family of the server itself (rfc4213) and we
- * don't care which is used.  The gateways will be
- * selected based on the destination address and the
- * source address has no relavence.
- *
- * Links can also be stacked on top of each other.
- * This can be used, for example, to represent a tunnel
- * interface that runs on top of a physical interface.
- *
- * @hide
  */
 public class LinkProperties implements Parcelable {
     // The interface described by the network link.
@@ -73,6 +58,7 @@
     private Hashtable<String, LinkProperties> mStackedLinks =
         new Hashtable<String, LinkProperties>();
 
+    // @hide
     public static class CompareResult<T> {
         public Collection<T> removed = new ArrayList<T>();
         public Collection<T> added = new ArrayList<T>();
@@ -89,10 +75,8 @@
     }
 
     public LinkProperties() {
-        clear();
     }
 
-    // copy constructor instead of clone
     public LinkProperties(LinkProperties source) {
         if (source != null) {
             mIfaceName = source.getInterfaceName();
@@ -109,6 +93,12 @@
         }
     }
 
+    /**
+     * Sets the interface name for this link.  All {@link RouteInfo} already set for this
+     * will have their interface changed to match this new value.
+     *
+     * @param iface The name of the network interface used for this link.
+     */
     public void setInterfaceName(String iface) {
         mIfaceName = iface;
         ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size());
@@ -118,10 +108,16 @@
         mRoutes = newRoutes;
     }
 
+    /**
+     * Gets the interface name for this link.  May be {@code null} if not set.
+     *
+     * @return The interface name set for this link or {@code null}.
+     */
     public String getInterfaceName() {
         return mIfaceName;
     }
 
+    // @hide
     public Collection<String> getAllInterfaceNames() {
         Collection interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
         if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
@@ -132,7 +128,14 @@
     }
 
     /**
-     * Returns all the addresses on this link.
+     * Returns all the addresses on this link.  We often think of a link having a single address,
+     * however, particularly with Ipv6 several addresses are typical.  Note that the
+     * {@code LinkProperties} actually contains {@link LinkAddress} objects which also include
+     * prefix lengths for each address.  This is a simplified utility alternative to
+     * {@link LinkProperties#getLinkAddresses}.
+     *
+     * @return An umodifiable {@link Collection} of {@link InetAddress} for this link.
+     * @hide
      */
     public Collection<InetAddress> getAddresses() {
         Collection<InetAddress> addresses = new ArrayList<InetAddress>();
@@ -144,6 +147,7 @@
 
     /**
      * Returns all the addresses on this link and all the links stacked above it.
+     * @hide
      */
     public Collection<InetAddress> getAllAddresses() {
         Collection<InetAddress> addresses = new ArrayList<InetAddress>();
@@ -166,7 +170,8 @@
     }
 
     /**
-     * Adds a link address if it does not exist, or updates it if it does.
+     * Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the
+     * same address/prefix does not already exist.  If it does exist it is replaced.
      * @param address The {@code LinkAddress} to add.
      * @return true if {@code address} was added or updated, false otherwise.
      */
@@ -190,9 +195,10 @@
     }
 
     /**
-     * Removes a link address. Specifically, removes the link address, if any, for which
-     * {@code isSameAddressAs(toRemove)} returns true.
-     * @param address A {@code LinkAddress} specifying the address to remove.
+     * Removes a {@link LinkAddress} from this {@code LinkProperties}.  Specifically, matches
+     * and {@link LinkAddress} with the same address and prefix.
+     *
+     * @param toRemove A {@link LinkAddress} specifying the address to remove.
      * @return true if the address was removed, false if it did not exist.
      */
     public boolean removeLinkAddress(LinkAddress toRemove) {
@@ -205,7 +211,10 @@
     }
 
     /**
-     * Returns all the addresses on this link.
+     * Returns all the {@link LinkAddress} on this link.  Typically a link will have
+     * one IPv4 address and one or more IPv6 addresses.
+     *
+     * @return An unmodifiable {@link Collection} of {@link LinkAddress} for this link.
      */
     public Collection<LinkAddress> getLinkAddresses() {
         return Collections.unmodifiableCollection(mLinkAddresses);
@@ -213,6 +222,7 @@
 
     /**
      * Returns all the addresses on this link and all the links stacked above it.
+     * @hide
      */
     public Collection<LinkAddress> getAllLinkAddresses() {
         Collection<LinkAddress> addresses = new ArrayList<LinkAddress>();
@@ -224,7 +234,11 @@
     }
 
     /**
-     * Replaces the LinkAddresses on this link with the given collection of addresses.
+     * Replaces the {@link LinkAddress} in this {@code LinkProperties} with
+     * the given {@link Collection} of {@link LinkAddress}.
+     *
+     * @param addresses The {@link Collection} of {@link LinkAddress} to set in this
+     *                  object.
      */
     public void setLinkAddresses(Collection<LinkAddress> addresses) {
         mLinkAddresses.clear();
@@ -233,26 +247,64 @@
         }
     }
 
+    /**
+     * Adds the given {@link InetAddress} to the list of DNS servers.
+     *
+     * @param dns The {@link InetAddress} to add to the list of DNS servers.
+     */
     public void addDns(InetAddress dns) {
         if (dns != null) mDnses.add(dns);
     }
 
+    /**
+     * Returns all the {@link LinkAddress} for DNS servers on this link.
+     *
+     * @return An umodifiable {@link Collection} of {@link InetAddress} for DNS servers on
+     *         this link.
+     */
     public Collection<InetAddress> getDnses() {
         return Collections.unmodifiableCollection(mDnses);
     }
 
-    public String getDomains() {
-        return mDomains;
-    }
-
+    /**
+     * Sets the DNS domain search path used on this link.
+     *
+     * @param domains A {@link String} listing in priority order the comma separated
+     *                domains to search when resolving host names on this link.
+     */
     public void setDomains(String domains) {
         mDomains = domains;
     }
 
+    /**
+     * Get the DNS domains search path set for this link.
+     *
+     * @return A {@link String} containing the comma separated domains to search when resolving
+     *         host names on this link.
+     */
+    public String getDomains() {
+        return mDomains;
+    }
+
+    /**
+     * Sets the Maximum Transmission Unit size to use on this link.  This should not be used
+     * unless the system default (1500) is incorrect.  Values less than 68 or greater than
+     * 10000 will be ignored.
+     *
+     * @param mtu The MTU to use for this link.
+     * @hide
+     */
     public void setMtu(int mtu) {
         mMtu = mtu;
     }
 
+    /**
+     * Gets any non-default MTU size set for this link.  Note that if the default is being used
+     * this will return 0.
+     *
+     * @return The mtu value set for this link.
+     * @hide
+     */
     public int getMtu() {
         return mMtu;
     }
@@ -264,6 +316,14 @@
             mIfaceName);
     }
 
+    /**
+     * Adds a {@link RouteInfo} to this {@code LinkProperties}.  If the {@link RouteInfo}
+     * had an interface name set and that differs from the interface set for this
+     * {@code LinkProperties} an {@link IllegalArgumentException} will be thrown.  The
+     * proper course is to add either un-named or properly named {@link RouteInfo}.
+     *
+     * @param route A {@link RouteInfo} to add to this object.
+     */
     public void addRoute(RouteInfo route) {
         if (route != null) {
             String routeIface = route.getInterface();
@@ -277,7 +337,9 @@
     }
 
     /**
-     * Returns all the routes on this link.
+     * Returns all the {@link RouteInfo} set on this link.
+     *
+     * @return An unmodifiable {@link Collection} of {@link RouteInfo} for this link.
      */
     public Collection<RouteInfo> getRoutes() {
         return Collections.unmodifiableCollection(mRoutes);
@@ -285,6 +347,7 @@
 
     /**
      * Returns all the routes on this link and all the links stacked above it.
+     * @hide
      */
     public Collection<RouteInfo> getAllRoutes() {
         Collection<RouteInfo> routes = new ArrayList();
@@ -295,9 +358,22 @@
         return routes;
     }
 
+    /**
+     * Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none.
+     * Note that Http Proxies are only a hint - the system recommends their use, but it does
+     * not enforce it and applications may ignore them.
+     *
+     * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
+     */
     public void setHttpProxy(ProxyInfo proxy) {
         mHttpProxy = proxy;
     }
+
+    /**
+     * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link.
+     *
+     * @return The {@link ProxyInfo} set on this link
+     */
     public ProxyInfo getHttpProxy() {
         return mHttpProxy;
     }
@@ -311,6 +387,7 @@
      *
      * @param link The link to add.
      * @return true if the link was stacked, false otherwise.
+     * @hide
      */
     public boolean addStackedLink(LinkProperties link) {
         if (link != null && link.getInterfaceName() != null) {
@@ -328,6 +405,7 @@
      *
      * @param link The link to remove.
      * @return true if the link was removed, false otherwise.
+     * @hide
      */
     public boolean removeStackedLink(LinkProperties link) {
         if (link != null && link.getInterfaceName() != null) {
@@ -339,6 +417,7 @@
 
     /**
      * Returns all the links stacked on top of this link.
+     * @hide
      */
     public Collection<LinkProperties> getStackedLinks() {
         Collection<LinkProperties> stacked = new ArrayList<LinkProperties>();
@@ -348,6 +427,9 @@
         return Collections.unmodifiableCollection(stacked);
     }
 
+    /**
+     * Clears this object to its initial state.
+     */
     public void clear() {
         mIfaceName = null;
         mLinkAddresses.clear();
@@ -433,6 +515,7 @@
      *
      * @param target LinkProperties to compare.
      * @return {@code true} if both are identical, {@code false} otherwise.
+     * @hide
      */
     public boolean isIdenticalInterfaceName(LinkProperties target) {
         return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
@@ -443,6 +526,7 @@
      *
      * @param target LinkProperties to compare.
      * @return {@code true} if both are identical, {@code false} otherwise.
+     * @hide
      */
     public boolean isIdenticalAddresses(LinkProperties target) {
         Collection<InetAddress> targetAddresses = target.getAddresses();
@@ -456,6 +540,7 @@
      *
      * @param target LinkProperties to compare.
      * @return {@code true} if both are identical, {@code false} otherwise.
+     * @hide
      */
     public boolean isIdenticalDnses(LinkProperties target) {
         Collection<InetAddress> targetDnses = target.getDnses();
@@ -474,6 +559,7 @@
      *
      * @param target LinkProperties to compare.
      * @return {@code true} if both are identical, {@code false} otherwise.
+     * @hide
      */
     public boolean isIdenticalRoutes(LinkProperties target) {
         Collection<RouteInfo> targetRoutes = target.getRoutes();
@@ -486,6 +572,7 @@
      *
      * @param target LinkProperties to compare.
      * @return {@code true} if both are identical, {@code false} otherwise.
+     * @hide
      */
     public boolean isIdenticalHttpProxy(LinkProperties target) {
         return getHttpProxy() == null ? target.getHttpProxy() == null :
@@ -497,6 +584,7 @@
      *
      * @param target LinkProperties to compare.
      * @return {@code true} if both are identical, {@code false} otherwise.
+     * @hide
      */
     public boolean isIdenticalStackedLinks(LinkProperties target) {
         if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
@@ -517,6 +605,7 @@
      *
      * @param target LinkProperties to compare.
      * @return {@code true} if both are identical, {@code false} otherwise.
+     * @hide
      */
     public boolean isIdenticalMtu(LinkProperties target) {
         return getMtu() == target.getMtu();
@@ -534,10 +623,6 @@
      * 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
      * 2. Worst case performance is O(n^2).
      *
-     * This method does not check that stacked interfaces are equal, because
-     * stacked interfaces are not so much a property of the link as a
-     * description of connections between links.
-     *
      * @param obj the object to be tested for equality.
      * @return {@code true} if both objects are equal, {@code false} otherwise.
      */
@@ -547,7 +632,11 @@
         if (!(obj instanceof LinkProperties)) return false;
 
         LinkProperties target = (LinkProperties) obj;
-
+        /**
+         * This method does not check that stacked interfaces are equal, because
+         * stacked interfaces are not so much a property of the link as a
+         * description of connections between links.
+         */
         return isIdenticalInterfaceName(target) &&
                 isIdenticalAddresses(target) &&
                 isIdenticalDnses(target) &&
@@ -563,6 +652,7 @@
      *
      * @param target a LinkProperties with the new list of addresses
      * @return the differences between the addresses.
+     * @hide
      */
     public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
         /*
@@ -591,6 +681,7 @@
      *
      * @param target a LinkProperties with the new list of dns addresses
      * @return the differences between the DNS addresses.
+     * @hide
      */
     public CompareResult<InetAddress> compareDnses(LinkProperties target) {
         /*
@@ -620,6 +711,7 @@
      *
      * @param target a LinkProperties with the new list of routes
      * @return the differences between the routes.
+     * @hide
      */
     public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
         /*
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index ac1289b..e0d69e3 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -20,20 +20,34 @@
 import android.os.Parcel;
 
 import java.net.InetAddress;
+import java.net.Socket;
 import java.net.UnknownHostException;
+import javax.net.SocketFactory;
 
 /**
- * Identifies the Network.
- * @hide
+ * Identifies a {@code Network}.  This is supplied to applications via
+ * {@link ConnectivityManager.NetworkCallbackListener} in response to
+ * {@link ConnectivityManager#requestNetwork} or {@link ConnectivityManager#listenForNetwork}.
+ * It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis
+ * through a targeted {@link SocketFactory} or process-wide via {@link #bindProcess}.
  */
 public class Network implements Parcelable {
 
+    /**
+     * @hide
+     */
     public final int netId;
 
+    /**
+     * @hide
+     */
     public Network(int netId) {
         this.netId = netId;
     }
 
+    /**
+     * @hide
+     */
     public Network(Network that) {
         this.netId = that.netId;
     }
@@ -64,6 +78,45 @@
         return InetAddress.getByNameOnNet(host, netId);
     }
 
+    /**
+     * Returns a {@link SocketFactory} bound to this network.  Any {@link Socket} created by
+     * this factory will have its traffic sent over this {@code Network}.  Note that if this
+     * {@code Network} ever disconnects, this factory and any {@link Socket} it produced in the
+     * past or future will cease to work.
+     *
+     * @return a {@link SocketFactory} which produces {@link Socket} instances bound to this
+     *         {@code Network}.
+     */
+    public SocketFactory socketFactory() {
+        return null;
+    }
+
+    /**
+     * Binds the current process to this network.  All sockets created in the future (and not
+     * explicitly bound via a bound {@link SocketFactory} (see {@link Network#socketFactory})
+     * will be bound to this network.  Note that if this {@code Network} ever disconnects
+     * all sockets created in this way will cease to work.  This is by design so an application
+     * doesn't accidentally use sockets it thinks are still bound to a particular {@code Network}.
+     */
+    public void bindProcess() {
+    }
+
+    /**
+     * A static utility method to return any {@code Network} currently bound by this process.
+     *
+     * @return {@code Network} to which this process is bound.
+     */
+    public static Network getProcessBoundNetwork() {
+        return null;
+    }
+
+    /**
+     * Clear any process specific {@code Network} binding.  This reverts a call to
+     * {@link Network#bindProcess}.
+     */
+    public static void unbindProcess() {
+    }
+
     // implement the Parcelable interface
     public int describeContents() {
         return 0;
@@ -84,4 +137,14 @@
                 return new Network[size];
             }
     };
+
+    public boolean equals(Object obj) {
+        if (obj instanceof Network == false) return false;
+        Network other = (Network)obj;
+        return this.netId == other.netId;
+    }
+
+    public int hashCode() {
+        return netId * 11;
+    }
 }
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 4b85398..c2b06a2 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -66,6 +66,7 @@
     private AsyncChannel mAsyncChannel;
     private final String LOG_TAG;
     private static final boolean DBG = true;
+    private static final boolean VDBG = true;
     // TODO - this class shouldn't cache data or it runs the risk of getting out of sync
     // Make the API require each of these when any is updated so we have the data we need,
     // without caching.
@@ -266,11 +267,14 @@
      */
     private void evalScores() {
         if (mConnectionRequested) {
+            if (VDBG) log("evalScores - already trying - size=" + mNetworkRequests.size());
             // already trying
             return;
         }
+        if (VDBG) log("evalScores!");
         for (int i=0; i < mNetworkRequests.size(); i++) {
             int score = mNetworkRequests.valueAt(i).score;
+            if (VDBG) log(" checking request Min " + score + " vs my score " + mNetworkScore);
             if (score < mNetworkScore) {
                 // have a request that has a lower scored network servicing it
                 // (or no network) than we could provide, so lets connect!
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 8005e5c..35274f1 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -30,13 +30,31 @@
 import java.util.Set;
 
 /**
- * A class representing the capabilities of a network
- * @hide
+ * This class represents the capabilities of a network.  This is used both to specify
+ * needs to {@link ConnectivityManager} and when inspecting a network.
+ *
+ * Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
+ * of network selection.  Rather than indicate a need for Wi-Fi because an application
+ * needs high bandwidth and risk obselence when a new, fast network appears (like LTE),
+ * the application should specify it needs high bandwidth.  Similarly if an application
+ * needs an unmetered network for a bulk transfer it can specify that rather than assuming
+ * all cellular based connections are metered and all Wi-Fi based connections are not.
  */
 public final class NetworkCapabilities implements Parcelable {
     private static final String TAG = "NetworkCapabilities";
     private static final boolean DBG = false;
 
+    public NetworkCapabilities() {
+    }
+
+    public NetworkCapabilities(NetworkCapabilities nc) {
+        if (nc != null) {
+            mNetworkCapabilities = nc.mNetworkCapabilities;
+            mTransportTypes = nc.mTransportTypes;
+            mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
+            mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
+        }
+    }
 
     /**
      * Represents the network's capabilities.  If any are specified they will be satisfied
@@ -45,28 +63,99 @@
     private long mNetworkCapabilities = (1 << NET_CAPABILITY_NOT_RESTRICTED);
 
     /**
-     * Values for NetworkCapabilities.  Roughly matches/extends deprecated
-     * ConnectivityManager TYPE_*
+     * Indicates this is a network that has the ability to reach the
+     * carrier's MMSC for sending and receiving MMS messages.
      */
     public static final int NET_CAPABILITY_MMS            = 0;
+
+    /**
+     * Indicates this is a network that has the ability to reach the carrier's
+     * SUPL server, used to retrieve GPS information.
+     */
     public static final int NET_CAPABILITY_SUPL           = 1;
+
+    /**
+     * Indicates this is a network that has the ability to reach the carrier's
+     * DUN or tethering gateway.
+     */
     public static final int NET_CAPABILITY_DUN            = 2;
+
+    /**
+     * Indicates this is a network that has the ability to reach the carrier's
+     * FOTA portal, used for over the air updates.
+     */
     public static final int NET_CAPABILITY_FOTA           = 3;
+
+    /**
+     * Indicates this is a network that has the ability to reach the carrier's
+     * IMS servers, used for network registration and signaling.
+     */
     public static final int NET_CAPABILITY_IMS            = 4;
+
+    /**
+     * Indicates this is a network that has the ability to reach the carrier's
+     * CBS servers, used for carrier specific services.
+     */
     public static final int NET_CAPABILITY_CBS            = 5;
+
+    /**
+     * Indicates this is a network that has the ability to reach a Wi-Fi direct
+     * peer.
+     */
     public static final int NET_CAPABILITY_WIFI_P2P       = 6;
+
+    /**
+     * Indicates this is a network that has the ability to reach a carrier's
+     * Initial Attach servers.
+     */
     public static final int NET_CAPABILITY_IA             = 7;
+
+    /**
+     * Indicates this is a network that has the ability to reach a carrier's
+     * RCS servers, used for Rich Communication Services.
+     */
     public static final int NET_CAPABILITY_RCS            = 8;
+
+    /**
+     * Indicates this is a network that has the ability to reach a carrier's
+     * XCAP servers, used for configuration and control.
+     */
     public static final int NET_CAPABILITY_XCAP           = 9;
+
+    /**
+     * Indicates this is a network that has the ability to reach a carrier's
+     * Emergency IMS servers, used for network signaling during emergency calls.
+     */
     public static final int NET_CAPABILITY_EIMS           = 10;
+
+    /**
+     * Indicates that this network is unmetered.
+     */
     public static final int NET_CAPABILITY_NOT_METERED    = 11;
+
+    /**
+     * Indicates that this network should be able to reach the internet.
+     */
     public static final int NET_CAPABILITY_INTERNET       = 12;
-    /** Set by default */
+
+    /**
+     * Indicates that this network is available for general use.  If this is not set
+     * applications should not attempt to communicate on this network.  Note that this
+     * is simply informative and not enforcement - enforcement is handled via other means.
+     * Set by default.
+     */
     public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
 
     private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
     private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_RESTRICTED;
 
+    /**
+     * Adds the given capability to this {@code NetworkCapability} instance.
+     * Multiple capabilities may be applied sequentially.  Note that when searching
+     * for a network to satisfy a request, all capabilities requested must be satisfied.
+     *
+     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
+     */
     public void addNetworkCapability(int networkCapability) {
         if (networkCapability < MIN_NET_CAPABILITY ||
                 networkCapability > MAX_NET_CAPABILITY) {
@@ -74,6 +163,12 @@
         }
         mNetworkCapabilities |= 1 << networkCapability;
     }
+
+    /**
+     * Removes (if found) the given capability from this {@code NetworkCapability} instance.
+     *
+     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
+     */
     public void removeNetworkCapability(int networkCapability) {
         if (networkCapability < MIN_NET_CAPABILITY ||
                 networkCapability > MAX_NET_CAPABILITY) {
@@ -81,9 +176,23 @@
         }
         mNetworkCapabilities &= ~(1 << networkCapability);
     }
+
+    /**
+     * Gets all the capabilities set on this {@code NetworkCapability} instance.
+     *
+     * @return a {@link Collection} of {@code NetworkCapabilities.NET_CAPABILITY_*} values
+     *         for this instance.
+     */
     public Collection<Integer> getNetworkCapabilities() {
         return enumerateBits(mNetworkCapabilities);
     }
+
+    /**
+     * Tests for the presence of a capabilitity on this instance.
+     *
+     * @param networkCapability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
+     * @return {@code true} if set on this instance.
+     */
     public boolean hasCapability(int networkCapability) {
         if (networkCapability < MIN_NET_CAPABILITY ||
                 networkCapability > MAX_NET_CAPABILITY) {
@@ -124,31 +233,74 @@
     private long mTransportTypes;
 
     /**
-     * Values for TransportType
+     * Indicates this network uses a Cellular transport.
      */
     public static final int TRANSPORT_CELLULAR = 0;
+
+    /**
+     * Indicates this network uses a Wi-Fi transport.
+     */
     public static final int TRANSPORT_WIFI = 1;
+
+    /**
+     * Indicates this network uses a Bluetooth transport.
+     */
     public static final int TRANSPORT_BLUETOOTH = 2;
+
+    /**
+     * Indicates this network uses an Ethernet transport.
+     */
     public static final int TRANSPORT_ETHERNET = 3;
 
     private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
     private static final int MAX_TRANSPORT = TRANSPORT_ETHERNET;
 
+    /**
+     * Adds the given transport type to this {@code NetworkCapability} instance.
+     * Multiple transports may be applied sequentially.  Note that when searching
+     * for a network to satisfy a request, any listed in the request will satisfy the request.
+     * For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
+     * {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
+     * to be selected.  This is logically different than
+     * {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
+     *
+     * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
+     */
     public void addTransportType(int transportType) {
         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
             throw new IllegalArgumentException("TransportType out of range");
         }
         mTransportTypes |= 1 << transportType;
     }
+
+    /**
+     * Removes (if found) the given transport from this {@code NetworkCapability} instance.
+     *
+     * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
+     */
     public void removeTransportType(int transportType) {
         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
             throw new IllegalArgumentException("TransportType out of range");
         }
         mTransportTypes &= ~(1 << transportType);
     }
+
+    /**
+     * Gets all the transports set on this {@code NetworkCapability} instance.
+     *
+     * @return a {@link Collection} of {@code NetworkCapabilities.TRANSPORT_*} values
+     *         for this instance.
+     */
     public Collection<Integer> getTransportTypes() {
         return enumerateBits(mTransportTypes);
     }
+
+    /**
+     * Tests for the presence of a transport on this instance.
+     *
+     * @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
+     * @return {@code true} if set on this instance.
+     */
     public boolean hasTransport(int transportType) {
         if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
             return false;
@@ -175,15 +327,58 @@
     private int mLinkUpBandwidthKbps;
     private int mLinkDownBandwidthKbps;
 
+    /**
+     * Sets the upstream bandwidth for this network in Kbps.  This always only refers to
+     * the estimated first hop transport bandwidth.
+     * <p>
+     * Note that when used to request a network, this specifies the minimum acceptable.
+     * When received as the state of an existing network this specifies the typical
+     * first hop bandwidth expected.  This is never measured, but rather is inferred
+     * from technology type and other link parameters.  It could be used to differentiate
+     * between very slow 1xRTT cellular links and other faster networks or even between
+     * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
+     * fast backhauls and slow backhauls.
+     *
+     * @param upKbps the estimated first hop upstream (device to network) bandwidth.
+     */
     public void setLinkUpstreamBandwidthKbps(int upKbps) {
         mLinkUpBandwidthKbps = upKbps;
     }
+
+    /**
+     * Retrieves the upstream bandwidth for this network in Kbps.  This always only refers to
+     * the estimated first hop transport bandwidth.
+     *
+     * @return The estimated first hop upstream (device to network) bandwidth.
+     */
     public int getLinkUpstreamBandwidthKbps() {
         return mLinkUpBandwidthKbps;
     }
+
+    /**
+     * Sets the downstream bandwidth for this network in Kbps.  This always only refers to
+     * the estimated first hop transport bandwidth.
+     * <p>
+     * Note that when used to request a network, this specifies the minimum acceptable.
+     * When received as the state of an existing network this specifies the typical
+     * first hop bandwidth expected.  This is never measured, but rather is inferred
+     * from technology type and other link parameters.  It could be used to differentiate
+     * between very slow 1xRTT cellular links and other faster networks or even between
+     * 802.11b vs 802.11AC wifi technologies.  It should not be used to differentiate between
+     * fast backhauls and slow backhauls.
+     *
+     * @param downKbps the estimated first hop downstream (network to device) bandwidth.
+     */
     public void setLinkDownstreamBandwidthKbps(int downKbps) {
         mLinkDownBandwidthKbps = downKbps;
     }
+
+    /**
+     * Retrieves the downstream bandwidth for this network in Kbps.  This always only refers to
+     * the estimated first hop transport bandwidth.
+     *
+     * @return The estimated first hop downstream (network to device) bandwidth.
+     */
     public int getLinkDownstreamBandwidthKbps() {
         return mLinkDownBandwidthKbps;
     }
@@ -243,19 +438,6 @@
                 (mLinkDownBandwidthKbps * 13));
     }
 
-    public NetworkCapabilities() {
-    }
-
-    public NetworkCapabilities(NetworkCapabilities nc) {
-        if (nc != null) {
-            mNetworkCapabilities = nc.mNetworkCapabilities;
-            mTransportTypes = nc.mTransportTypes;
-            mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
-            mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
-        }
-    }
-
-    // Parcelable
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index b3ae3f5..480cb05 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -22,11 +22,19 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * @hide
+ * Defines a request for a network, made by calling {@link ConnectivityManager#requestNetwork}
+ * or {@link ConnectivityManager#listenForNetwork}.
+ *
+ * This token records the {@link NetworkCapabilities} used to make the request and identifies
+ * the request.  It should be used to release the request via
+ * {@link ConnectivityManager#releaseNetworkRequest} when the network is no longer desired.
  */
 public class NetworkRequest implements Parcelable {
     /**
-     * The NetworkCapabilities that define this request
+     * The {@link NetworkCapabilities} that define this request.  This should not be modified.
+     * The networkCapabilities of the request are set when
+     * {@link ConnectivityManager#requestNetwork} is called and the value is presented here
+     * as a convenient reminder of what was requested.
      */
     public final NetworkCapabilities networkCapabilities;
 
@@ -34,7 +42,7 @@
      * Identifies the request.  NetworkRequests should only be constructed by
      * the Framework and given out to applications as tokens to be used to identify
      * the request.
-     * TODO - make sure this input is checked whenever a NR is passed in a public API
+     * @hide
      */
     public final int requestId;
 
@@ -45,31 +53,18 @@
      */
     public final boolean needsBroadcasts;
 
-    private static final AtomicInteger sNextRequestId = new AtomicInteger(1);
-
     /**
      * @hide
      */
-    public NetworkRequest(NetworkCapabilities nc) {
-        this(nc, false, sNextRequestId.getAndIncrement());
-    }
-
-    /**
-     * @hide
-     */
-    public NetworkRequest(NetworkCapabilities nc, boolean needsBroadcasts) {
-        this(nc, needsBroadcasts, sNextRequestId.getAndIncrement());
-    }
-
-    /**
-     * @hide
-     */
-    private NetworkRequest(NetworkCapabilities nc, boolean needsBroadcasts, int rId) {
+    public NetworkRequest(NetworkCapabilities nc, boolean needsBroadcasts, int rId) {
         requestId = rId;
         networkCapabilities = nc;
         this.needsBroadcasts = needsBroadcasts;
     }
 
+    /**
+     * @hide
+     */
     public NetworkRequest(NetworkRequest that) {
         networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
         requestId = that.requestId;
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index 1d051dd..ad8e4f7 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -25,22 +25,26 @@
 import java.net.Inet6Address;
 
 import java.util.Collection;
+import java.util.Objects;
 
 /**
- * A simple container for route information.
+ * Represents a network route.
+ * <p>
+ * This is used both to describe static network configuration and live network
+ * configuration information.
  *
- * In order to be used, a route must have a destination prefix and:
- *
- * - A gateway address (next-hop, for gatewayed routes), or
- * - An interface (for directly-connected routes), or
- * - Both a gateway and an interface.
- *
- * This class does not enforce these constraints because there is code that
- * uses RouteInfo objects to store directly-connected routes without interfaces.
- * Such objects cannot be used directly, but can be put into a LinkProperties
- * object which then specifies the interface.
- *
- * @hide
+ * A route contains three pieces of information:
+ * <ul>
+ * <li>a destination {@link LinkAddress} for directly-connected subnets.  If this is
+ *     {@code null} it indicates a default route of the address family (IPv4 or IPv6)
+ *     implied by the gateway IP address.
+ * <li>a gateway {@link InetAddress} for default routes.  If this is {@code null} it
+ *     indicates a directly-connected route.
+ * <li>an interface (which may be unspecified).
+ * </ul>
+ * Either the destination or the gateway may be {@code null}, but not both.  If the
+ * destination and gateway are both specified, they must be of the same address family
+ * (IPv4 or IPv6).
  */
 public class RouteInfo implements Parcelable {
     /**
@@ -67,10 +71,10 @@
      *
      * If destination is null, then gateway must be specified and the
      * constructed route is either the IPv4 default route <code>0.0.0.0</code>
-     * if @gateway is an instance of {@link Inet4Address}, or the IPv6 default
+     * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
      * route <code>::/0</code> if gateway is an instance of
      * {@link Inet6Address}.
-     *
+     * <p>
      * destination and gateway may not both be null.
      *
      * @param destination the destination prefix
@@ -102,28 +106,64 @@
 
         mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
                 destination.getNetworkPrefixLength()), destination.getNetworkPrefixLength());
+        if ((destination.getAddress() instanceof Inet4Address &&
+                 (gateway instanceof Inet4Address == false)) ||
+                (destination.getAddress() instanceof Inet6Address &&
+                 (gateway instanceof Inet6Address == false))) {
+            throw new IllegalArgumentException("address family mismatch in RouteInfo constructor");
+        }
         mGateway = gateway;
         mInterface = iface;
         mIsDefault = isDefault();
         mIsHost = isHost();
     }
 
+    /**
+     * Constructs a {@code RouteInfo} object.
+     *
+     * If destination is null, then gateway must be specified and the
+     * constructed route is either the IPv4 default route <code>0.0.0.0</code>
+     * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
+     * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
+     * <p>
+     * Destination and gateway may not both be null.
+     *
+     * @param destination the destination address and prefix in a {@link LinkAddress}
+     * @param gateway the {@link InetAddress} to route packets through
+     */
     public RouteInfo(LinkAddress destination, InetAddress gateway) {
         this(destination, gateway, null);
     }
 
+    /**
+     * Constructs a default {@code RouteInfo} object.
+     *
+     * @param gateway the {@link InetAddress} to route packets through
+     */
     public RouteInfo(InetAddress gateway) {
         this(null, gateway, null);
     }
 
-    public RouteInfo(LinkAddress host) {
-        this(host, null, null);
+    /**
+     * Constructs a {@code RouteInfo} object representing a direct connected subnet.
+     *
+     * @param destination the {@link LinkAddress} describing the address and prefix
+     *                    length of the subnet.
+     */
+    public RouteInfo(LinkAddress destination) {
+        this(destination, null, null);
     }
 
+    /**
+     * @hide
+     */
     public static RouteInfo makeHostRoute(InetAddress host, String iface) {
         return makeHostRoute(host, null, iface);
     }
 
+    /**
+     * @hide
+     */
     public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) {
         if (host == null) return null;
 
@@ -153,31 +193,108 @@
         return val;
     }
 
-
+    /**
+     * Retrieves the destination address and prefix length in the form of a {@link LinkAddress}.
+     *
+     * @return {@link LinkAddress} specifying the destination.  This is never {@code null}.
+     */
     public LinkAddress getDestination() {
         return mDestination;
     }
 
+    /**
+     * Retrieves the gateway or next hop {@link InetAddress} for this route.
+     *
+     * @return {@link InetAddress} specifying the gateway or next hop.  This may be
+     &                             {@code null} for a directly-connected route."
+     */
     public InetAddress getGateway() {
         return mGateway;
     }
 
+    /**
+     * Retrieves the interface used for this route if specified, else {@code null}.
+     *
+     * @return The name of the interface used for this route.
+     */
     public String getInterface() {
         return mInterface;
     }
 
+    /**
+     * Indicates if this route is a default route (ie, has no destination specified).
+     *
+     * @return {@code true} if the destination has a prefix length of 0.
+     */
     public boolean isDefaultRoute() {
         return mIsDefault;
     }
 
+    /**
+     * Indicates if this route is a host route (ie, matches only a single host address).
+     *
+     * @return {@code true} if the destination has a prefix length of 32/128 for v4/v6.
+     * @hide
+     */
     public boolean isHostRoute() {
         return mIsHost;
     }
 
+    /**
+     * Indicates if this route has a next hop ({@code true}) or is directly-connected
+     * ({@code false}).
+     *
+     * @return {@code true} if a gateway is specified
+     * @hide
+     */
     public boolean hasGateway() {
         return mHasGateway;
     }
 
+    /**
+     * Determines whether the destination and prefix of this route includes the specified
+     * address.
+     *
+     * @param destination A {@link InetAddress} to test to see if it would match this route.
+     * @return {@code true} if the destination and prefix length cover the given address.
+     */
+    public boolean matches(InetAddress destination) {
+        if (destination == null) return false;
+
+        // match the route destination and destination with prefix length
+        InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
+                mDestination.getNetworkPrefixLength());
+
+        return mDestination.getAddress().equals(dstNet);
+    }
+
+    /**
+     * Find the route from a Collection of routes that best matches a given address.
+     * May return null if no routes are applicable.
+     * @param routes a Collection of RouteInfos to chose from
+     * @param dest the InetAddress your trying to get to
+     * @return the RouteInfo from the Collection that best fits the given address
+     *
+     * @hide
+     */
+    public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
+        if ((routes == null) || (dest == null)) return null;
+
+        RouteInfo bestRoute = null;
+        // pick a longest prefix match under same address type
+        for (RouteInfo route : routes) {
+            if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
+                if ((bestRoute != null) &&
+                        (bestRoute.mDestination.getNetworkPrefixLength() >=
+                        route.mDestination.getNetworkPrefixLength())) {
+                    continue;
+                }
+                if (route.matches(dest)) bestRoute = route;
+            }
+        }
+        return bestRoute;
+    }
+
     public String toString() {
         String val = "";
         if (mDestination != null) val = mDestination.toString();
@@ -185,10 +302,37 @@
         return val;
     }
 
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+
+        if (!(obj instanceof RouteInfo)) return false;
+
+        RouteInfo target = (RouteInfo) obj;
+
+        return Objects.equals(mDestination, target.getDestination()) &&
+                Objects.equals(mGateway, target.getGateway()) &&
+                Objects.equals(mInterface, target.getInterface());
+    }
+
+    public int hashCode() {
+        return (mDestination == null ? 0 : mDestination.hashCode() * 41)
+                + (mGateway == null ? 0 :mGateway.hashCode() * 47)
+                + (mInterface == null ? 0 :mInterface.hashCode() * 67)
+                + (mIsDefault ? 3 : 7);
+    }
+
+    /**
+     * Implement the Parcelable interface
+     * @hide
+     */
     public int describeContents() {
         return 0;
     }
 
+    /**
+     * Implement the Parcelable interface
+     * @hide
+     */
     public void writeToParcel(Parcel dest, int flags) {
         if (mDestination == null) {
             dest.writeByte((byte) 0);
@@ -208,38 +352,10 @@
         dest.writeString(mInterface);
     }
 
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-
-        if (!(obj instanceof RouteInfo)) return false;
-
-        RouteInfo target = (RouteInfo) obj;
-
-        boolean sameDestination = ( mDestination == null) ?
-                target.getDestination() == null
-                : mDestination.equals(target.getDestination());
-
-        boolean sameAddress = (mGateway == null) ?
-                target.getGateway() == null
-                : mGateway.equals(target.getGateway());
-
-        boolean sameInterface = (mInterface == null) ?
-                target.getInterface() == null
-                : mInterface.equals(target.getInterface());
-
-        return sameDestination && sameAddress && sameInterface
-            && mIsDefault == target.mIsDefault;
-    }
-
-    @Override
-    public int hashCode() {
-        return (mDestination == null ? 0 : mDestination.hashCode() * 41)
-            + (mGateway == null ? 0 :mGateway.hashCode() * 47)
-            + (mInterface == null ? 0 :mInterface.hashCode() * 67)
-            + (mIsDefault ? 3 : 7);
-    }
-
+    /**
+     * Implement the Parcelable interface.
+     * @hide
+     */
     public static final Creator<RouteInfo> CREATOR =
         new Creator<RouteInfo>() {
         public RouteInfo createFromParcel(Parcel in) {
@@ -279,39 +395,4 @@
             return new RouteInfo[size];
         }
     };
-
-    protected boolean matches(InetAddress destination) {
-        if (destination == null) return false;
-
-        // match the route destination and destination with prefix length
-        InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
-                mDestination.getNetworkPrefixLength());
-
-        return mDestination.getAddress().equals(dstNet);
-    }
-
-    /**
-     * Find the route from a Collection of routes that best matches a given address.
-     * May return null if no routes are applicable.
-     * @param routes a Collection of RouteInfos to chose from
-     * @param dest the InetAddress your trying to get to
-     * @return the RouteInfo from the Collection that best fits the given address
-     */
-    public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
-        if ((routes == null) || (dest == null)) return null;
-
-        RouteInfo bestRoute = null;
-        // pick a longest prefix match under same address type
-        for (RouteInfo route : routes) {
-            if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
-                if ((bestRoute != null) &&
-                        (bestRoute.mDestination.getNetworkPrefixLength() >=
-                        route.mDestination.getNetworkPrefixLength())) {
-                    continue;
-                }
-                if (route.matches(dest)) bestRoute = route;
-            }
-        }
-        return bestRoute;
-    }
 }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0708e55..cc132be 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -20,7 +20,7 @@
 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
-import static android.net.ConnectivityManager.NetworkCallbacks;
+import static android.net.ConnectivityManager.NetworkCallbackListener;
 import static android.net.ConnectivityManager.TYPE_BLUETOOTH;
 import static android.net.ConnectivityManager.TYPE_DUMMY;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
@@ -193,6 +193,9 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = true; // STOPSHIP
 
+    // network sampling debugging
+    private static final boolean SAMPLE_DBG = false;
+
     private static final boolean LOGD_RULES = false;
 
     // TODO: create better separation between radio types and network types
@@ -219,10 +222,10 @@
     // Set network sampling interval at 12 minutes, this way, even if the timers get
     // aggregated, it will fire at around 15 minutes, which should allow us to
     // aggregate this timer with other timers (specially the socket keep alive timers)
-    private static final int DEFAULT_SAMPLING_INTERVAL_IN_SECONDS = (VDBG ? 30 : 12 * 60);
+    private static final int DEFAULT_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 12 * 60);
 
     // start network sampling a minute after booting ...
-    private static final int DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS = (VDBG ? 30 : 60);
+    private static final int DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 60);
 
     AlarmManager mAlarmManager;
 
@@ -504,10 +507,14 @@
 
     TelephonyManager mTelephonyManager;
 
+    // sequence number for Networks
     private final static int MIN_NET_ID = 10; // some reserved marks
     private final static int MAX_NET_ID = 65535;
     private int mNextNetId = MIN_NET_ID;
 
+    // sequence number of NetworkRequests
+    private int mNextNetworkRequestId = 1;
+
     public ConnectivityService(Context context, INetworkManagementService netd,
             INetworkStatsService statsService, INetworkPolicyManager policyManager) {
         // Currently, omitting a NetworkFactory will create one internally
@@ -523,7 +530,7 @@
         NetworkCapabilities netCap = new NetworkCapabilities();
         netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
         netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-        mDefaultRequest = new NetworkRequest(netCap, true);
+        mDefaultRequest = new NetworkRequest(netCap, true, nextNetworkRequestId());
         NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
                 NetworkRequestInfo.REQUEST);
         mNetworkRequests.put(mDefaultRequest, nri);
@@ -770,6 +777,10 @@
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
     }
 
+    private synchronized int nextNetworkRequestId() {
+        return mNextNetworkRequestId++;
+    }
+
     private synchronized int nextNetId() {
         int netId = mNextNetId;
         if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
@@ -3216,6 +3227,7 @@
             // tell the network currently servicing this that it's no longer interested
             NetworkAgentInfo affectedNetwork = mNetworkForRequestId.get(nri.request.requestId);
             if (affectedNetwork != null) {
+                mNetworkForRequestId.remove(nri.request.requestId);
                 affectedNetwork.networkRequests.remove(nri.request.requestId);
                 if (VDBG) {
                     log(" Removing from current network " + affectedNetwork.name() + ", leaving " +
@@ -5267,7 +5279,7 @@
             throw new IllegalArgumentException("Bad timeout specified");
         }
         NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
-                networkCapabilities));
+                networkCapabilities), false, nextNetworkRequestId());
         if (DBG) log("requestNetwork for " + networkRequest);
         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
                 NetworkRequestInfo.REQUEST);
@@ -5293,7 +5305,7 @@
         enforceAccessPermission();
 
         NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
-                networkCapabilities));
+                networkCapabilities), false, nextNetworkRequestId());
         if (DBG) log("listenForNetwork for " + networkRequest);
         NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
                 NetworkRequestInfo.LISTEN);
@@ -5491,10 +5503,29 @@
             } catch (Exception e) {
                 loge("Exception in setDnsServersForNetwork: " + e);
             }
-            // TODO - setprop "net.dnsX"
+            NetworkAgentInfo defaultNai = mNetworkForRequestId.get(mDefaultRequest.requestId);
+            if (defaultNai != null && defaultNai.network.netId == netId) {
+                setDefaultDnsSystemProperties(dnses);
+            }
         }
     }
 
+    private void setDefaultDnsSystemProperties(Collection<InetAddress> dnses) {
+        int last = 0;
+        for (InetAddress dns : dnses) {
+            ++last;
+            String key = "net.dns" + last;
+            String value = dns.getHostAddress();
+            SystemProperties.set(key, value);
+        }
+        for (int i = last + 1; i <= mNumDnsEntries; ++i) {
+            String key = "net.dns" + i;
+            SystemProperties.set(key, "");
+        }
+        mNumDnsEntries = last;
+    }
+
+
     private void updateCapabilities(NetworkAgentInfo networkAgent,
             NetworkCapabilities networkCapabilities) {
         // TODO - what else here?  Verify still satisfies everybody?
@@ -5610,6 +5641,11 @@
                     if (mDefaultRequest.requestId == nri.request.requestId) {
                         isNewDefault = true;
                         updateActiveDefaultNetwork(newNetwork);
+                        if (newNetwork.linkProperties != null) {
+                            setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnses());
+                        } else {
+                            setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 3884ab0..096ab66 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -74,6 +74,14 @@
         mIsStarted = false;
         mIsRunning = false;
         mLP = new LinkProperties();
+
+        // If this is a runtime restart, it's possible that clatd is already
+        // running, but we don't know about it. If so, stop it.
+        try {
+            if (mNMService.isClatdStarted()) {
+                mNMService.stopClatd();
+            }
+        } catch(RemoteException e) {}  // Well, we tried.
     }
 
     /**
@@ -198,13 +206,13 @@
                 NetworkUtils.resetConnections(
                     CLAT_INTERFACE_NAME,
                     NetworkUtils.RESET_IPV4_ADDRESSES);
+                mBaseLP.removeStackedLink(mLP);
+                updateConnectivityService();
             }
             Slog.i(TAG, "interface " + CLAT_INTERFACE_NAME +
                    " removed, mIsRunning = " + mIsRunning + " -> false");
             mIsRunning = false;
-            mBaseLP.removeStackedLink(mLP);
             mLP.clear();
-            updateConnectivityService();
             Slog.i(TAG, "mLP = " + mLP);
         }
     }