Allow unprivileged NetworkCallbacks to see other UIDs' networks.

Currently, unprivileged apps can call getAllNetworks() to see
all networks on the system, even networks that do not apply to
them. Allow them to do this via NetworkCallbacks as well.

This is the last piece of information that was only available
through getAllNetworks, so this CL deprecates that API.

Bug: 187921303
Test: new unit tests
Test: CTS test in other CL in topic
Change-Id: I30f1021927d3c8eae6525116c61ff4a4acecff6d
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 13ecb12..33f4d14 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -70,7 +70,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
     method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
     method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
-    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
+    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
     method @Deprecated public boolean getBackgroundDataSetting();
     method @Nullable public android.net.Network getBoundNetworkForProcess();
     method public int getConnectionOwnerUid(int, @NonNull java.net.InetSocketAddress, @NonNull java.net.InetSocketAddress);
@@ -406,6 +406,7 @@
     method @NonNull public android.net.NetworkRequest.Builder clearCapabilities();
     method public android.net.NetworkRequest.Builder removeCapability(int);
     method public android.net.NetworkRequest.Builder removeTransportType(int);
+    method @NonNull public android.net.NetworkRequest.Builder setIncludeOtherUidNetworks(boolean);
     method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
     method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
   }
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 5a53af4..93455bc 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -1433,10 +1433,18 @@
      * Returns an array of all {@link Network} currently tracked by the
      * framework.
      *
+     * @deprecated This method does not provide any notification of network state changes, forcing
+     *             apps to call it repeatedly. This is inefficient and prone to race conditions.
+     *             Apps should use methods such as
+     *             {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} instead.
+     *             Apps that desire to obtain information about networks that do not apply to them
+     *             can use {@link NetworkRequest.Builder#setIncludeOtherUidNetworks}.
+     *
      * @return an array of {@link Network} objects.
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     @NonNull
+    @Deprecated
     public Network[] getAllNetworks() {
         try {
             return mService.getAllNetworks();
diff --git a/framework/src/android/net/NetworkRequest.java b/framework/src/android/net/NetworkRequest.java
index a384109..a71dbbf 100644
--- a/framework/src/android/net/NetworkRequest.java
+++ b/framework/src/android/net/NetworkRequest.java
@@ -287,10 +287,15 @@
         }
 
         /**
-         * Set the watched UIDs for this request. This will be reset and wiped out unless
-         * the calling app holds the CHANGE_NETWORK_STATE permission.
+         * Sets this request to match only networks that apply to the specified UIDs.
          *
-         * @param uids The watched UIDs as a set of {@code Range<Integer>}, or null for everything.
+         * By default, the set of UIDs is the UID of the calling app, and this request will match
+         * any network that applies to the app. Setting it to {@code null} will observe any
+         * network on the system, even if it does not apply to this app. In this case, any
+         * {@link NetworkSpecifier} set on this request will be redacted or removed to prevent the
+         * application deducing restricted information such as location.
+         *
+         * @param uids The UIDs as a set of {@code Range<Integer>}, or null for everything.
          * @return The builder to facilitate chaining.
          * @hide
          */
@@ -517,6 +522,30 @@
             mNetworkCapabilities.setSubscriptionIds(subIds);
             return this;
         }
+
+        /**
+         * Specifies whether the built request should also match networks that do not apply to the
+         * calling UID.
+         *
+         * By default, the built request will only match networks that apply to the calling UID.
+         * If this method is called with {@code true}, the built request will match any network on
+         * the system that matches the other parameters of the request. In this case, any
+         * information in the built request that is subject to redaction for security or privacy
+         * purposes, such as a {@link NetworkSpecifier}, will be redacted or removed to prevent the
+         * application deducing sensitive information.
+         *
+         * @param include Whether to match networks that do not apply to the calling UID.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setIncludeOtherUidNetworks(boolean include) {
+            if (include) {
+                mNetworkCapabilities.setUids(null);
+            } else {
+                mNetworkCapabilities.setSingleUid(Process.myUid());
+            }
+            return this;
+        }
     }
 
     // implement the Parcelable interface