Deprecate static ConnectivityManager.get/setProcessDefaultNetwork() functions.

These functions risk hitting an unchecked Exception due to ConnectivityManager
not being instantiated yet.  Also, change Network.openConnection() to throw a
checked Exception rather than an unchecked Exception when ConnectivityManager
is not yet instantiated.

bug:19416463
Change-Id: Ie1e2b3238aec0343d267c76b64927073f2f05f85
diff --git a/api/current.txt b/api/current.txt
index 98b15c7..365948b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16954,16 +16954,18 @@
 
   public class ConnectivityManager {
     method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
+    method public boolean bindProcessToNetwork(android.net.Network);
     method public android.net.NetworkInfo getActiveNetworkInfo();
     method public android.net.NetworkInfo[] getAllNetworkInfo();
     method public android.net.Network[] getAllNetworks();
     method public deprecated boolean getBackgroundDataSetting();
+    method public android.net.Network getBoundNetworkForProcess();
     method public android.net.LinkProperties getLinkProperties(android.net.Network);
     method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
     method public android.net.NetworkInfo getNetworkInfo(int);
     method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
     method public deprecated int getNetworkPreference();
-    method public static android.net.Network getProcessDefaultNetwork();
+    method public static deprecated android.net.Network getProcessDefaultNetwork();
     method public boolean isActiveNetworkMetered();
     method public boolean isDefaultNetworkActive();
     method public static boolean isNetworkTypeValid(int);
@@ -16975,7 +16977,7 @@
     method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
     method public deprecated boolean requestRouteToHost(int, int);
     method public deprecated void setNetworkPreference(int);
-    method public static boolean setProcessDefaultNetwork(android.net.Network);
+    method public static deprecated boolean setProcessDefaultNetwork(android.net.Network);
     method public deprecated int startUsingNetworkFeature(int, java.lang.String);
     method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
     method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
diff --git a/api/system-current.txt b/api/system-current.txt
index ae94a9c..ca32e66 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -18215,16 +18215,18 @@
 
   public class ConnectivityManager {
     method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
+    method public boolean bindProcessToNetwork(android.net.Network);
     method public android.net.NetworkInfo getActiveNetworkInfo();
     method public android.net.NetworkInfo[] getAllNetworkInfo();
     method public android.net.Network[] getAllNetworks();
     method public deprecated boolean getBackgroundDataSetting();
+    method public android.net.Network getBoundNetworkForProcess();
     method public android.net.LinkProperties getLinkProperties(android.net.Network);
     method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
     method public android.net.NetworkInfo getNetworkInfo(int);
     method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
     method public deprecated int getNetworkPreference();
-    method public static android.net.Network getProcessDefaultNetwork();
+    method public static deprecated android.net.Network getProcessDefaultNetwork();
     method public boolean isActiveNetworkMetered();
     method public boolean isDefaultNetworkActive();
     method public static boolean isNetworkTypeValid(int);
@@ -18236,7 +18238,7 @@
     method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
     method public deprecated boolean requestRouteToHost(int, int);
     method public deprecated void setNetworkPreference(int);
-    method public static boolean setProcessDefaultNetwork(android.net.Network);
+    method public static deprecated boolean setProcessDefaultNetwork(android.net.Network);
     method public deprecated int startUsingNetworkFeature(int, java.lang.String);
     method public deprecated int stopUsingNetworkFeature(int, java.lang.String);
     method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f2be45c..c3a1555 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -849,10 +849,10 @@
         }
 
         public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
-            final Network network = ConnectivityManager.getProcessDefaultNetwork();
+            final ConnectivityManager cm = ConnectivityManager.from(getSystemContext());
+            final Network network = cm.getBoundNetworkForProcess();
             if (network != null) {
-                Proxy.setHttpProxySystemProperty(
-                        ConnectivityManager.from(getSystemContext()).getDefaultProxy());
+                Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
             } else {
                 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
             }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a00246f..767113e 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1201,7 +1201,7 @@
      * @return {@code true} on success, {@code false} on failure
      *
      * @deprecated Deprecated in favor of the {@link #requestNetwork},
-     *             {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api.
+     *             {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} api.
      */
     public boolean requestRouteToHost(int networkType, int hostAddress) {
         return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress));
@@ -1219,7 +1219,7 @@
      * @return {@code true} on success, {@code false} on failure
      * @hide
      * @deprecated Deprecated in favor of the {@link #requestNetwork} and
-     *             {@link #setProcessDefaultNetwork} api.
+     *             {@link #bindProcessToNetwork} api.
      */
     public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
         try {
@@ -1344,7 +1344,7 @@
      * listener.
      * <p>
      * If the process default network has been set with
-     * {@link ConnectivityManager#setProcessDefaultNetwork} this function will not
+     * {@link ConnectivityManager#bindProcessToNetwork} this function will not
      * reflect the process's default, but the system default.
      *
      * @param l The listener to be told when the network is active.
@@ -1429,11 +1429,20 @@
      *               situations where a Context pointer is unavailable.
      * @hide
      */
-    public static ConnectivityManager getInstance() {
-        if (sInstance == null) {
+    static ConnectivityManager getInstanceOrNull() {
+        return sInstance;
+    }
+
+    /**
+     * @deprecated - use getSystemService. This is a kludge to support static access in certain
+     *               situations where a Context pointer is unavailable.
+     * @hide
+     */
+    private static ConnectivityManager getInstance() {
+        if (getInstanceOrNull() == null) {
             throw new IllegalStateException("No ConnectivityManager yet constructed");
         }
-        return sInstance;
+        return getInstanceOrNull();
     }
 
     /**
@@ -1769,7 +1778,7 @@
     /**
      * Get the current default HTTP proxy settings.  If a global proxy is set it will be returned,
      * otherwise if this process is bound to a {@link Network} using
-     * {@link #setProcessDefaultNetwork} then that {@code Network}'s proxy is returned, otherwise
+     * {@link #bindProcessToNetwork} then that {@code Network}'s proxy is returned, otherwise
      * the default network's proxy is returned.
      *
      * @return the {@link ProxyInfo} for the current HTTP proxy, or {@code null} if no
@@ -1777,7 +1786,7 @@
      * @hide
      */
     public ProxyInfo getDefaultProxy() {
-        final Network network = getProcessDefaultNetwork();
+        final Network network = getBoundNetworkForProcess();
         if (network != null) {
             final ProxyInfo globalProxy = getGlobalProxy();
             if (globalProxy != null) return globalProxy;
@@ -2337,9 +2346,8 @@
      * successfully finding a network for the applications request.  Retrieve it with
      * {@link android.content.Intent#getParcelableExtra(String)}.
      * <p>
-     * Note that if you intend to invoke {@link #setProcessDefaultNetwork} or
-     * {@link Network#openConnection(java.net.URL)} then you must get a
-     * ConnectivityManager instance before doing so.
+     * Note that if you intend to invoke {@link Network#openConnection(java.net.URL)}
+     * then you must get a ConnectivityManager instance before doing so.
      */
     public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
 
@@ -2458,15 +2466,42 @@
      * Sockets created by Network.getSocketFactory().createSocket() and
      * performing network-specific host name resolutions via
      * {@link Network#getAllByName Network.getAllByName} is preferred to calling
-     * {@code setProcessDefaultNetwork}.
+     * {@code bindProcessToNetwork}.
      *
      * @param network The {@link Network} to bind the current process to, or {@code null} to clear
      *                the current binding.
      * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
      */
+    public boolean bindProcessToNetwork(Network network) {
+        // Forcing callers to call thru non-static function ensures ConnectivityManager
+        // instantiated.
+        return setProcessDefaultNetwork(network);
+    }
+
+    /**
+     * Binds the current process to {@code network}.  All Sockets created in the future
+     * (and not explicitly bound via a bound SocketFactory from
+     * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to
+     * {@code network}.  All host name resolutions will be limited to {@code network} as well.
+     * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to
+     * work and all host name resolutions will fail.  This is by design so an application doesn't
+     * accidentally use Sockets it thinks are still bound to a particular {@link Network}.
+     * To clear binding pass {@code null} for {@code network}.  Using individually bound
+     * Sockets created by Network.getSocketFactory().createSocket() and
+     * performing network-specific host name resolutions via
+     * {@link Network#getAllByName Network.getAllByName} is preferred to calling
+     * {@code setProcessDefaultNetwork}.
+     *
+     * @param network The {@link Network} to bind the current process to, or {@code null} to clear
+     *                the current binding.
+     * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
+     * @deprecated This function can throw {@link IllegalStateException}.  Use
+     *             {@link #bindProcessToNetwork} instead.  {@code bindProcessToNetwork}
+     *             is a direct replacement.
+     */
     public static boolean setProcessDefaultNetwork(Network network) {
         int netId = (network == null) ? NETID_UNSET : network.netId;
-        if (netId == NetworkUtils.getNetworkBoundToProcess()) {
+        if (netId == NetworkUtils.getBoundNetworkForProcess()) {
             return true;
         }
         if (NetworkUtils.bindProcessToNetwork(netId)) {
@@ -2486,19 +2521,34 @@
 
     /**
      * Returns the {@link Network} currently bound to this process via
-     * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound.
+     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
      *
      * @return {@code Network} to which this process is bound, or {@code null}.
      */
+    public Network getBoundNetworkForProcess() {
+        // Forcing callers to call thru non-static function ensures ConnectivityManager
+        // instantiated.
+        return getProcessDefaultNetwork();
+    }
+
+    /**
+     * Returns the {@link Network} currently bound to this process via
+     * {@link #bindProcessToNetwork}, or {@code null} if no {@link Network} is explicitly bound.
+     *
+     * @return {@code Network} to which this process is bound, or {@code null}.
+     * @deprecated Using this function can lead to other functions throwing
+     *             {@link IllegalStateException}.  Use {@link #getBoundNetworkForProcess} instead.
+     *             {@code getBoundNetworkForProcess} is a direct replacement.
+     */
     public static Network getProcessDefaultNetwork() {
-        int netId = NetworkUtils.getNetworkBoundToProcess();
+        int netId = NetworkUtils.getBoundNetworkForProcess();
         if (netId == NETID_UNSET) return null;
         return new Network(netId);
     }
 
     /**
      * Binds host resolutions performed by this process to {@code network}.
-     * {@link #setProcessDefaultNetwork} takes precedence over this setting.
+     * {@link #bindProcessToNetwork} takes precedence over this setting.
      *
      * @param network The {@link Network} to bind host resolutions from the current process to, or
      *                {@code null} to clear the current binding.
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 5c12696..df6eb99 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -51,7 +51,7 @@
  * {@link ConnectivityManager#registerNetworkCallback} calls.
  * 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 ConnectivityManager#setProcessDefaultNetwork}.
+ * {@link ConnectivityManager#bindProcessToNetwork}.
  */
 public class Network implements Parcelable {
 
@@ -245,7 +245,10 @@
      * @see java.net.URL#openConnection()
      */
     public URLConnection openConnection(URL url) throws IOException {
-        final ConnectivityManager cm = ConnectivityManager.getInstance();
+        final ConnectivityManager cm = ConnectivityManager.getInstanceOrNull();
+        if (cm == null) {
+            throw new IOException("No ConnectivityManager yet constructed, please construct one");
+        }
         // TODO: Should this be optimized to avoid fetching the global proxy for every request?
         ProxyInfo proxyInfo = cm.getGlobalProxy();
         if (proxyInfo == null) {
@@ -299,7 +302,7 @@
     /**
      * Binds the specified {@link DatagramSocket} to this {@code Network}. All data traffic on the
      * socket will be sent on this {@code Network}, irrespective of any process-wide network binding
-     * set by {@link ConnectivityManager#setProcessDefaultNetwork}. The socket must not be
+     * set by {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be
      * connected.
      */
     public void bindSocket(DatagramSocket socket) throws IOException {
@@ -316,7 +319,7 @@
     /**
      * Binds the specified {@link Socket} to this {@code Network}. All data traffic on the socket
      * will be sent on this {@code Network}, irrespective of any process-wide network binding set by
-     * {@link ConnectivityManager#setProcessDefaultNetwork}. The socket must not be connected.
+     * {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be connected.
      */
     public void bindSocket(Socket socket) throws IOException {
         // Apparently, the kernel doesn't update a connected TCP socket's routing upon mark changes.
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 02fbe73..29dd8ad 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -159,7 +159,7 @@
      * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
      * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
      */
-    public native static int getNetworkBoundToProcess();
+    public native static int getBoundNetworkForProcess();
 
     /**
      * Binds host resolutions performed by this process to the network designated by {@code netId}.
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index c26af06..a0e65eb 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -679,7 +679,7 @@
          *
          * By default, all traffic from apps is forwarded through the VPN interface and it is not
          * possible for apps to side-step the VPN. If this method is called, apps may use methods
-         * such as {@link ConnectivityManager#setProcessDefaultNetwork} to instead send/receive
+         * such as {@link ConnectivityManager#bindProcessToNetwork} to instead send/receive
          * directly over the underlying network or any other network they have permissions for.
          *
          * @return this {@link Builder} object to facilitate chaining of method calls.
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index e97d61e..52da137 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -268,7 +268,7 @@
     return (jboolean) !setNetworkForProcess(netId);
 }
 
-static jint android_net_utils_getNetworkBoundToProcess(JNIEnv *env, jobject thiz)
+static jint android_net_utils_getBoundNetworkForProcess(JNIEnv *env, jobject thiz)
 {
     return getNetworkForProcess();
 }
@@ -306,7 +306,7 @@
     { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
     { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork },
-    { "getNetworkBoundToProcess", "()I", (void*) android_net_utils_getNetworkBoundToProcess },
+    { "getBoundNetworkForProcess", "()I", (void*) android_net_utils_getBoundNetworkForProcess },
     { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
     { "bindSocketToNetwork", "(II)I", (void*) android_net_utils_bindSocketToNetwork },
     { "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index d898555..77765a4 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -99,7 +99,7 @@
         final ConnectivityManager cm = ConnectivityManager.from(this);
         final Network network = new Network(mNetId);
         // Also initializes proxy system properties.
-        cm.setProcessDefaultNetwork(network);
+        cm.bindProcessToNetwork(network);
 
         // Proxy system properties must be initialized before setContentView is called because
         // setContentView initializes the WebView logic which in turn reads the system properties.