Merge "Remove unused api."
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index f0fadbe..0297c84 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -284,6 +284,98 @@
     public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
 
     /**
+     * Broadcast Action: A connection has been established to a new network
+     * but a captive portal has been detected preventing internet connectivity.
+     * This broadcast is sent out prior to providing the user with a
+     * notification allowing them to sign into the network, as such it should
+     * only be used by apps that can automatically and silently (without user
+     * interaction) log into specific captive portals.  It should not be used
+     * by apps that prompt the user to sign in, as the user has not yet
+     * indicated they want to proceed with signing in.
+     * The new network is not the default network so it can only be accessed via
+     * the {@link Network} extra {@link #EXTRA_NETWORK}.
+     * This is an ordered broadcast and so it is perfectly acceptable for
+     * multiple receivers to in turn consider whether they are best suited to
+     * address the captive portal.
+     * A receiver should abort the broadcast if they are sure they are the
+     * appropriate handler of the captive portal.  If the broadcast is aborted,
+     * the result code must be set to one of the following:
+     * <ul>
+     *   <li>{@link #CAPTIVE_PORTAL_SIGNED_IN} The receiver has signed into the
+     *       captive portal.  After being verified to provide internet
+     *       connectivity, this network will be made the default (assuming
+     *       it is preferred over all other active networks).
+     *   </li>
+     *   <li>{@link #CAPTIVE_PORTAL_DISCONNECT} The receiver is familiar with
+     *       this captive portal and knows sign-in is impossible or the user
+     *       has indicated they do not want to pursue sign-in.  No other apps
+     *       will be given the option of signing in to the network.
+     *   </li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CAPTIVE_PORTAL_DETECTED =
+            "android.net.conn.CAPTIVE_PORTAL_DETECTED";
+
+    /**
+     * Broadcast Action: A connection has been established to a new network,
+     * a captive portal has been detected preventing internet connectivity,
+     * the user was notified, and elected to sign into the captive portal.
+     * It may be used by apps that prompt the user to sign in.
+     * The new network is not the default network so it can only be accessed via
+     * the {@link Network} extra {@link #EXTRA_NETWORK}.
+     * This is an ordered broadcast and so it is perfectly acceptable for
+     * multiple receivers to in turn consider whether they are best suited to
+     * address the captive portal.
+     * A receiver should abort the broadcast if they are sure they are the
+     * appropriate handler of the captive portal.  If the broadcast is aborted,
+     * the result code must be set to one of the following:
+     * <ul>
+     *   <li>{@link #CAPTIVE_PORTAL_SIGNED_IN} The receiver has signed into the
+     *       captive portal.  After being verified to provide internet
+     *       connectivity, this network will be made the default (assuming
+     *       it is preferred over all other active networks).
+     *   </li>
+     *   <li>{@link #CAPTIVE_PORTAL_DISCONNECT} The user has indicated they do
+     *       not want to pursue sign-in.  No other apps will be given the
+     *       option of signing in to the network.
+     *   </li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN =
+            "android.net.conn.CAPTIVE_PORTAL_SIGN_IN";
+
+    /**
+     * The lookup key for a {@link Network} object passed along with a
+     * {@link #ACTION_CAPTIVE_PORTAL_DETECTED} or
+     * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} intent.  This network is not the
+     * default network and must be accessed using this {@link Network} object.
+     * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
+     */
+    public static final String EXTRA_NETWORK = "network";
+
+    /**
+     * Specified as a result code of a {@link #ACTION_CAPTIVE_PORTAL_DETECTED} or
+     * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} receiver to indicate
+     * the receiver has signed into the
+     * captive portal.  After being verified to provide internet
+     * connectivity, this network will be made the default (assuming
+     * it is preferred over all other active networks).
+     */
+    public static final int CAPTIVE_PORTAL_SIGNED_IN = 1;
+
+    /**
+     * Specified as a result code of a {@link #ACTION_CAPTIVE_PORTAL_DETECTED} or
+     * {@link #ACTION_CAPTIVE_PORTAL_SIGN_IN} receiver to indicate
+     * the receiver is familiar with
+     * this captive portal and knows sign-in is impossible or the user
+     * has indicated they do not want to pursue sign-in.  No other apps will
+     * be given the option of signing in to the network.
+     */
+    public static final int CAPTIVE_PORTAL_DISCONNECT = 2;
+
+    /**
      * The absence of a connection type.
      * @hide
      */
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 8f6c46f..e865e88 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3332,6 +3332,12 @@
         }
         if (bestNetwork != null) {
             if (VDBG) log("using " + bestNetwork.name());
+            if (nri.isRequest && bestNetwork.networkInfo.isConnected()) {
+                // Cancel any lingering so the linger timeout doesn't teardown this network
+                // even though we have a request for it.
+                bestNetwork.networkLingered.clear();
+                bestNetwork.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
+            }
             bestNetwork.addRequest(nri.request);
             mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
             int legacyType = nri.request.legacyType;