Merge changes from topics "vcn04", "vcn12"
* changes:
[VCN12] Expose setSubIds/getSubIds APIs
[VCN04] Add Subscription Id set into NetworkCapabilities
diff --git a/framework/api/current.txt b/framework/api/current.txt
index 61ffaca..243e4ca 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -143,6 +143,7 @@
public static class ConnectivityManager.NetworkCallback {
ctor public ConnectivityManager.NetworkCallback();
+ ctor public ConnectivityManager.NetworkCallback(int);
method public void onAvailable(@NonNull android.net.Network);
method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
@@ -150,6 +151,7 @@
method public void onLosing(@NonNull android.net.Network, int);
method public void onLost(@NonNull android.net.Network);
method public void onUnavailable();
+ field public static final int FLAG_INCLUDE_LOCATION_INFO = 1; // 0x1
}
public static interface ConnectivityManager.OnNetworkActiveListener {
@@ -403,6 +405,10 @@
method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
}
+ public class ParseException extends java.lang.RuntimeException {
+ field public String response;
+ }
+
public class ProxyInfo implements android.os.Parcelable {
ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
method public static android.net.ProxyInfo buildDirectProxy(String, int);
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index 6df57c1..4b33366 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -7,8 +7,9 @@
public class ConnectivityManager {
method @NonNull @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public java.util.List<android.net.NetworkStateSnapshot> getAllNetworkStateSnapshot();
+ method @NonNull public static android.util.Range<java.lang.Integer> getIpSecNetIdRange();
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
- method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @Nullable android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
+ method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
}
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 45ed317..e9107b6 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -20,6 +20,7 @@
import static android.net.NetworkRequest.Type.BACKGROUND_REQUEST;
import static android.net.NetworkRequest.Type.LISTEN;
import static android.net.NetworkRequest.Type.REQUEST;
+import static android.net.NetworkRequest.Type.TRACK_BEST;
import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
import static android.net.QosCallback.QosCallbackRegistrationException;
@@ -43,6 +44,7 @@
import android.net.TetheringManager.StartTetheringCallback;
import android.net.TetheringManager.TetheringEventCallback;
import android.net.TetheringManager.TetheringRequest;
+import android.net.wifi.WifiNetworkSuggestion;
import android.os.Binder;
import android.os.Build;
import android.os.Build.VERSION_CODES;
@@ -1314,7 +1316,7 @@
}
/**
- * Returns an array of {@link android.net.NetworkCapabilities} objects, representing
+ * Returns an array of {@link NetworkCapabilities} objects, representing
* the Networks that applications run by the given user will use by default.
* @hide
*/
@@ -1394,11 +1396,19 @@
}
/**
- * Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This
+ * Get the {@link NetworkCapabilities} for the given {@link Network}. This
* will return {@code null} if the network is unknown.
*
+ * This will remove any location sensitive data in {@link TransportInfo} embedded in
+ * {@link NetworkCapabilities#getTransportInfo()}. Some transport info instances like
+ * {@link android.net.wifi.WifiInfo} contain location sensitive information. Retrieving
+ * this location sensitive information (subject to app's location permissions) will be
+ * noted by system. To include any location sensitive data in {@link TransportInfo},
+ * use a {@link NetworkCallback} with
+ * {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} flag.
+ *
* @param network The {@link Network} object identifying the network in question.
- * @return The {@link android.net.NetworkCapabilities} for the network, or {@code null}.
+ * @return The {@link NetworkCapabilities} for the network, or {@code null}.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@Nullable
@@ -3244,6 +3254,54 @@
*/
public static class NetworkCallback {
/**
+ * No flags associated with this callback.
+ * @hide
+ */
+ public static final int FLAG_NONE = 0;
+ /**
+ * Use this flag to include any location sensitive data in {@link NetworkCapabilities} sent
+ * via {@link #onCapabilitiesChanged(Network, NetworkCapabilities)}.
+ * <p>
+ * These include:
+ * <li> Some transport info instances (retrieved via
+ * {@link NetworkCapabilities#getTransportInfo()}) like {@link android.net.wifi.WifiInfo}
+ * contain location sensitive information.
+ * <li> OwnerUid (retrieved via {@link NetworkCapabilities#getOwnerUid()} is location
+ * sensitive for wifi suggestor apps (i.e using {@link WifiNetworkSuggestion}).</li>
+ * </p>
+ * <p>
+ * Note:
+ * <li> Retrieving this location sensitive information (subject to app's location
+ * permissions) will be noted by system. </li>
+ * <li> Without this flag any {@link NetworkCapabilities} provided via the callback does
+ * not include location sensitive info.
+ * </p>
+ */
+ public static final int FLAG_INCLUDE_LOCATION_INFO = 1 << 0;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = "FLAG_", value = {
+ FLAG_NONE,
+ FLAG_INCLUDE_LOCATION_INFO
+ })
+ public @interface Flag { }
+
+ /**
+ * All the valid flags for error checking.
+ */
+ private static final int VALID_FLAGS = FLAG_INCLUDE_LOCATION_INFO;
+
+ public NetworkCallback() {
+ this(FLAG_NONE);
+ }
+
+ public NetworkCallback(@Flag int flags) {
+ Preconditions.checkArgument((flags & VALID_FLAGS) == flags);
+ mFlags = flags;
+ }
+
+ /**
* Called when the framework connects to a new network to evaluate whether it satisfies this
* request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable}
* callback. There is no guarantee that this new network will satisfy any requests, or that
@@ -3380,7 +3438,7 @@
* calling these methods while in a callback may return an outdated or even a null object.
*
* @param network The {@link Network} whose capabilities have changed.
- * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
+ * @param networkCapabilities The new {@link NetworkCapabilities} for this
* network.
*/
public void onCapabilitiesChanged(@NonNull Network network,
@@ -3449,6 +3507,7 @@
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
private NetworkRequest networkRequest;
+ private final int mFlags;
}
/**
@@ -3638,14 +3697,15 @@
}
Messenger messenger = new Messenger(handler);
Binder binder = new Binder();
+ final int callbackFlags = callback.mFlags;
if (reqType == LISTEN) {
request = mService.listenForNetwork(
- need, messenger, binder, callingPackageName,
+ need, messenger, binder, callbackFlags, callingPackageName,
getAttributionTag());
} else {
request = mService.requestNetwork(
need, reqType.ordinal(), messenger, timeoutMs, binder, legacyType,
- callingPackageName, getAttributionTag());
+ callbackFlags, callingPackageName, getAttributionTag());
}
if (request != null) {
sCallbacks.put(request, callback);
@@ -3692,7 +3752,7 @@
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link NetworkCapabilities}.
*
* <p>This method will attempt to find the best network that matches the passed
* {@link NetworkRequest}, and to bring up one that does if none currently satisfies the
@@ -3776,7 +3836,7 @@
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link NetworkCapabilities}.
*
* This method behaves identically to {@link #requestNetwork(NetworkRequest, NetworkCallback)}
* but runs all the callbacks on the passed Handler.
@@ -3798,7 +3858,7 @@
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
+ * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
* by a timeout.
*
* This function behaves identically to the non-timed-out version
@@ -3833,7 +3893,7 @@
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
+ * Request a network to satisfy a set of {@link NetworkCapabilities}, limited
* by a timeout.
*
* This method behaves identically to
@@ -3878,7 +3938,7 @@
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
+ * Request a network to satisfy a set of {@link NetworkCapabilities}.
*
* This function behaves identically to the version that takes a NetworkCallback, but instead
* of {@link NetworkCallback} a {@link PendingIntent} is used. This means
@@ -4190,6 +4250,18 @@
}
/**
+ * @hide
+ */
+ // TODO: Make it public api.
+ @SuppressLint("ExecutorRegistration")
+ public void registerBestMatchingNetworkCallback(@NonNull NetworkRequest request,
+ @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
+ final NetworkCapabilities nc = request.networkCapabilities;
+ final CallbackHandler cbHandler = new CallbackHandler(handler);
+ sendRequestForNetwork(nc, networkCallback, 0, TRACK_BEST, TYPE_NONE, cbHandler);
+ }
+
+ /**
* Requests bandwidth update for a given {@link Network} and returns whether the update request
* is accepted by ConnectivityService. Once accepted, ConnectivityService will poll underlying
* network connection for updated bandwidth information. The caller will be notified via
@@ -4898,7 +4970,7 @@
}
/**
- * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, but
+ * Request a network to satisfy a set of {@link NetworkCapabilities}, but
* does not cause any networks to retain the NET_CAPABILITY_FOREGROUND capability. This can
* be used to request that the system provide a network without causing the network to be
* in the foreground.
@@ -4979,10 +5051,10 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK
})
public void requestBackgroundNetwork(@NonNull NetworkRequest request,
- @Nullable Handler handler, @NonNull NetworkCallback networkCallback) {
+ @NonNull Handler handler, @NonNull NetworkCallback networkCallback) {
final NetworkCapabilities nc = request.networkCapabilities;
sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST,
- TYPE_NONE, handler == null ? getDefaultHandler() : new CallbackHandler(handler));
+ TYPE_NONE, new CallbackHandler(handler));
}
/**
@@ -5040,4 +5112,21 @@
throw e.rethrowFromSystemServer();
}
}
+
+ // The first network ID of IPSec tunnel interface.
+ private static final int TUN_INTF_NETID_START = 0xFC00;
+ // The network ID range of IPSec tunnel interface.
+ private static final int TUN_INTF_NETID_RANGE = 0x0400;
+
+ /**
+ * Get the network ID range reserved for IPSec tunnel interfaces.
+ *
+ * @return A Range which indicates the network ID range of IPSec tunnel interface.
+ * @hide
+ */
+ @SystemApi(client = MODULE_LIBRARIES)
+ @NonNull
+ public static Range<Integer> getIpSecNetIdRange() {
+ return new Range(TUN_INTF_NETID_START, TUN_INTF_NETID_START + TUN_INTF_NETID_RANGE - 1);
+ }
}
diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index cd49258..f9393e3 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -143,7 +143,7 @@
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType,
in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
- String callingPackageName, String callingAttributionTag);
+ int callbackFlags, String callingPackageName, String callingAttributionTag);
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation, String callingPackageName, String callingAttributionTag);
@@ -151,7 +151,7 @@
void releasePendingNetworkRequest(in PendingIntent operation);
NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, in IBinder binder, String callingPackageName,
+ in Messenger messenger, in IBinder binder, int callbackFlags, String callingPackageName,
String callingAttributionTag);
void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index 4e1fd1c..058f3c9 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -25,6 +25,7 @@
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.ConnectivityManager.NetworkCallback;
+import android.net.wifi.WifiNetworkSuggestion;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -1050,6 +1051,16 @@
*
* Instances of NetworkCapabilities sent to apps without the appropriate permissions will have
* this field cleared out.
+ *
+ * <p>
+ * This field will only be populated for VPN and wifi network suggestor apps (i.e using
+ * {@link WifiNetworkSuggestion}), and only for the network they own.
+ * In the case of wifi network suggestors apps, this field is also location sensitive, so the
+ * app needs to hold {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. If the
+ * app targets SDK version greater than or equal to {@link Build.VERSION_CODES#S}, then they
+ * also need to use {@link NetworkCallback#FLAG_INCLUDE_LOCATION_INFO} to get the info in their
+ * callback. The app will be blamed for location access if this field is included.
+ * </p>
*/
public int getOwnerUid() {
return mOwnerUid;
diff --git a/framework/src/android/net/NetworkRequest.java b/framework/src/android/net/NetworkRequest.java
index 960d967..3fd95ee 100644
--- a/framework/src/android/net/NetworkRequest.java
+++ b/framework/src/android/net/NetworkRequest.java
@@ -114,6 +114,10 @@
* for the network (if any) that satisfies the default Internet
* request.
*
+ * - TRACK_BEST, which causes the framework to send callbacks about
+ * the single, highest scoring current network (if any) that matches
+ * the specified NetworkCapabilities.
+ *
* - BACKGROUND_REQUEST, like REQUEST but does not cause any networks
* to retain the NET_CAPABILITY_FOREGROUND capability. A network with
* no foreground requests is in the background. A network that has
@@ -136,6 +140,7 @@
REQUEST,
BACKGROUND_REQUEST,
TRACK_SYSTEM_DEFAULT,
+ TRACK_BEST,
};
/**
diff --git a/framework/src/android/net/NetworkState.java b/framework/src/android/net/NetworkState.java
index d010265..9b69674 100644
--- a/framework/src/android/net/NetworkState.java
+++ b/framework/src/android/net/NetworkState.java
@@ -22,7 +22,7 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Slog;
+import android.util.Log;
/**
* Snapshot of network state.
@@ -83,7 +83,7 @@
if (VALIDATE_ROAMING_STATE && networkInfo != null && networkCapabilities != null) {
if (networkInfo.isRoaming() == networkCapabilities
.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
- Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
+ Log.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
+ " and " + networkCapabilities);
}
}
diff --git a/framework/src/android/net/ParseException.java b/framework/src/android/net/ParseException.java
new file mode 100644
index 0000000..bcfdd7e
--- /dev/null
+++ b/framework/src/android/net/ParseException.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+
+/**
+ * Thrown when parsing failed.
+ */
+// See non-public class {@link WebAddress}.
+public class ParseException extends RuntimeException {
+ public String response;
+
+ ParseException(@NonNull String response) {
+ super(response);
+ this.response = response;
+ }
+
+ ParseException(@NonNull String response, @NonNull Throwable cause) {
+ super(response, cause);
+ this.response = response;
+ }
+}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 78853c7..afa3bd1 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -85,6 +85,7 @@
import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
import android.net.DataStallReportParcelable;
import android.net.DnsResolverServiceManager;
import android.net.ICaptivePortal;
@@ -190,7 +191,6 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.AsyncChannel;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.LocationPermissionChecker;
import com.android.internal.util.MessageUtils;
@@ -344,8 +344,7 @@
private String mCurrentTcpBufferSizes;
private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
- new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class,
- NetworkAgentInfo.class });
+ new Class[] { ConnectivityService.class, NetworkAgent.class, NetworkAgentInfo.class });
private enum ReapUnvalidatedNetworks {
// Tear down networks that have no chance (e.g. even if validated) of becoming
@@ -1100,7 +1099,8 @@
mNetworkRanker = new NetworkRanker();
final NetworkRequest defaultInternetRequest = createDefaultRequest();
mDefaultRequest = new NetworkRequestInfo(
- defaultInternetRequest, null, new Binder(),
+ defaultInternetRequest, null,
+ new Binder(), NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
null /* attributionTags */);
mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
mDefaultNetworkRequests.add(mDefaultRequest);
@@ -1356,7 +1356,9 @@
if (enable) {
handleRegisterNetworkRequest(new NetworkRequestInfo(
- networkRequest, null, new Binder(),
+ networkRequest, null,
+ new Binder(),
+ NetworkCallback.FLAG_INCLUDE_LOCATION_INFO,
null /* attributionTags */));
} else {
handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
@@ -1717,8 +1719,8 @@
result.put(
nai.network,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, mDeps.getCallingUid(), callingPackageName,
- callingAttributionTag));
+ nc, false /* includeLocationSensitiveInfo */,
+ mDeps.getCallingUid(), callingPackageName, callingAttributionTag));
}
}
@@ -1731,7 +1733,9 @@
result.put(
network,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, mDeps.getCallingUid(), callingPackageName,
+ nc,
+ false /* includeLocationSensitiveInfo */,
+ mDeps.getCallingUid(), callingPackageName,
callingAttributionTag));
}
}
@@ -1813,6 +1817,7 @@
enforceAccessPermission();
return createWithLocationInfoSanitizedIfNecessaryWhenParceled(
getNetworkCapabilitiesInternal(network),
+ false /* includeLocationSensitiveInfo */,
mDeps.getCallingUid(), callingPackageName, callingAttributionTag);
}
@@ -1846,8 +1851,8 @@
@VisibleForTesting
@Nullable
NetworkCapabilities createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- @Nullable NetworkCapabilities nc, int callerUid, @NonNull String callerPkgName,
- @Nullable String callingAttributionTag) {
+ @Nullable NetworkCapabilities nc, boolean includeLocationSensitiveInfo,
+ int callerUid, @NonNull String callerPkgName, @Nullable String callingAttributionTag) {
if (nc == null) {
return null;
}
@@ -1855,7 +1860,9 @@
final NetworkCapabilities newNc;
// Avoid doing location permission check if the transport info has no location sensitive
// data.
- if (nc.getTransportInfo() != null && nc.getTransportInfo().hasLocationSensitiveFields()) {
+ if (includeLocationSensitiveInfo
+ && nc.getTransportInfo() != null
+ && nc.getTransportInfo().hasLocationSensitiveFields()) {
hasLocationPermission =
hasLocationPermission(callerUid, callerPkgName, callingAttributionTag);
newNc = new NetworkCapabilities(nc, hasLocationPermission);
@@ -1872,6 +1879,16 @@
// Owner UIDs already checked above. No need to re-check.
return newNc;
}
+ // If the caller does not want location sensitive data & target SDK >= S, then mask info.
+ // Else include the owner UID iff the caller has location permission to provide backwards
+ // compatibility for older apps.
+ if (!includeLocationSensitiveInfo
+ && isTargetSdkAtleast(
+ Build.VERSION_CODES.S, callerUid, callerPkgName)) {
+ newNc.setOwnerUid(INVALID_UID);
+ return newNc;
+ }
+
if (hasLocationPermission == null) {
// Location permission not checked yet, check now for masking owner UID.
hasLocationPermission =
@@ -2890,22 +2907,6 @@
super(looper);
}
- private boolean maybeHandleAsyncChannelMessage(Message msg) {
- switch (msg.what) {
- default:
- return false;
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
- handleAsyncChannelHalfConnect(msg);
- break;
- }
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
- handleAsyncChannelDisconnected(msg);
- break;
- }
- }
- return true;
- }
-
private void maybeHandleNetworkAgentMessage(Message msg) {
final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
final NetworkAgentInfo nai = arg.first;
@@ -3197,8 +3198,7 @@
@Override
public void handleMessage(Message msg) {
- if (!maybeHandleAsyncChannelMessage(msg)
- && !maybeHandleNetworkMonitorMessage(msg)
+ if (!maybeHandleNetworkMonitorMessage(msg)
&& !maybeHandleNetworkAgentInfoMessage(msg)) {
maybeHandleNetworkAgentMessage(msg);
}
@@ -3462,21 +3462,6 @@
return false;
}
- private void handleAsyncChannelHalfConnect(Message msg) {
- ensureRunningOnConnectivityServiceThread();
- if (mNetworkProviderInfos.containsKey(msg.replyTo)) {
- if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- if (VDBG) log("NetworkFactory connected");
- // Finish setting up the full connection
- NetworkProviderInfo npi = mNetworkProviderInfos.get(msg.replyTo);
- sendAllRequestsToProvider(npi);
- } else {
- loge("Error connecting NetworkFactory");
- mNetworkProviderInfos.remove(msg.obj);
- }
- }
- }
-
private void handleNetworkAgentRegistered(Message msg) {
final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
if (!mNetworkAgentInfos.contains(nai)) {
@@ -3507,14 +3492,6 @@
}
}
- // This is a no-op if it's called with a message designating a provider that has
- // already been destroyed, because its reference will not be found in the relevant
- // maps.
- private void handleAsyncChannelDisconnected(Message msg) {
- NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo);
- if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name);
- }
-
// Destroys a network, remove references to it from the internal state managed by
// ConnectivityService, free its interfaces and clean up.
// Must be called on the Handler thread.
@@ -5155,8 +5132,8 @@
private final IBinder.DeathRecipient mDeathRecipient;
public final int providerId;
- NetworkProviderInfo(String name, Messenger messenger, AsyncChannel asyncChannel,
- int providerId, @NonNull IBinder.DeathRecipient deathRecipient) {
+ NetworkProviderInfo(String name, Messenger messenger, int providerId,
+ @NonNull IBinder.DeathRecipient deathRecipient) {
this.name = name;
this.messenger = messenger;
this.providerId = providerId;
@@ -5250,6 +5227,7 @@
private final IBinder mBinder;
final int mPid;
final int mUid;
+ final @NetworkCallback.Flag int mCallbackFlags;
@Nullable
final String mCallingAttributionTag;
// In order to preserve the mapping of NetworkRequest-to-callback when apps register
@@ -5297,17 +5275,26 @@
mPid = getCallingPid();
mUid = mDeps.getCallingUid();
mNetworkRequestCounter.incrementCountOrThrow(mUid);
+ /**
+ * Location sensitive data not included in pending intent. Only included in
+ * {@link NetworkCallback}.
+ */
+ mCallbackFlags = NetworkCallback.FLAG_NONE;
mCallingAttributionTag = callingAttributionTag;
}
NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final Messenger m,
- @Nullable final IBinder binder, @Nullable String callingAttributionTag) {
- this(Collections.singletonList(r), r, m, binder, callingAttributionTag);
+ @Nullable final IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
+ @Nullable String callingAttributionTag) {
+ this(Collections.singletonList(r), r, m, binder, callbackFlags, callingAttributionTag);
}
NetworkRequestInfo(@NonNull final List<NetworkRequest> r,
@NonNull final NetworkRequest requestForCallback, @Nullable final Messenger m,
- @Nullable final IBinder binder, @Nullable String callingAttributionTag) {
+ @Nullable final IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
+ @Nullable String callingAttributionTag) {
super();
ensureAllNetworkRequestsHaveType(r);
mRequests = initializeRequests(r);
@@ -5318,6 +5305,7 @@
mUid = mDeps.getCallingUid();
mPendingIntent = null;
mNetworkRequestCounter.incrementCountOrThrow(mUid);
+ mCallbackFlags = callbackFlags;
mCallingAttributionTag = callingAttributionTag;
try {
@@ -5359,6 +5347,7 @@
mUid = nri.mUid;
mPendingIntent = nri.mPendingIntent;
mNetworkRequestCounter.incrementCountOrThrow(mUid);
+ mCallbackFlags = nri.mCallbackFlags;
mCallingAttributionTag = nri.mCallingAttributionTag;
}
@@ -5408,7 +5397,8 @@
+ " callback request Id: "
+ mNetworkRequestForCallback.requestId
+ " " + mRequests
- + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
+ + (mPendingIntent == null ? "" : " to trigger " + mPendingIntent)
+ + "callback flags: " + mCallbackFlags;
}
}
@@ -5492,13 +5482,13 @@
}
}
- private boolean checkUnsupportedStartingFrom(int version, String callingPackageName) {
- final UserHandle user = UserHandle.getUserHandleForUid(mDeps.getCallingUid());
+ private boolean isTargetSdkAtleast(int version, int callingUid,
+ @NonNull String callingPackageName) {
+ final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
final PackageManager pm =
mContext.createContextAsUser(user, 0 /* flags */).getPackageManager();
try {
- final int callingVersion = pm.getApplicationInfo(
- callingPackageName, 0 /* flags */).targetSdkVersion;
+ final int callingVersion = pm.getTargetSdkVersion(callingPackageName);
if (callingVersion < version) return false;
} catch (PackageManager.NameNotFoundException e) { }
return true;
@@ -5507,10 +5497,11 @@
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder,
- int legacyType, @NonNull String callingPackageName,
+ int legacyType, int callbackFlags, @NonNull String callingPackageName,
@Nullable String callingAttributionTag) {
if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
- if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
+ if (isTargetSdkAtleast(Build.VERSION_CODES.M, mDeps.getCallingUid(),
+ callingPackageName)) {
throw new SecurityException("Insufficient permissions to specify legacy type");
}
}
@@ -5547,6 +5538,8 @@
// request if the app changes network state. http://b/29964605
enforceMeteredApnPolicy(networkCapabilities);
break;
+ case TRACK_BEST:
+ throw new UnsupportedOperationException("Not implemented yet");
default:
throw new IllegalArgumentException("Unsupported request type " + reqType);
}
@@ -5570,7 +5563,7 @@
final NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
nextNetworkRequestId(), reqType);
final NetworkRequestInfo nri = getNriToRegister(
- networkRequest, messenger, binder, callingAttributionTag);
+ networkRequest, messenger, binder, callbackFlags, callingAttributionTag);
if (DBG) log("requestNetwork for " + nri);
// For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
@@ -5605,6 +5598,7 @@
*/
private NetworkRequestInfo getNriToRegister(@NonNull final NetworkRequest nr,
@Nullable final Messenger msgr, @Nullable final IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
@Nullable String callingAttributionTag) {
final List<NetworkRequest> requests;
if (NetworkRequest.Type.TRACK_DEFAULT == nr.type) {
@@ -5613,7 +5607,8 @@
} else {
requests = Collections.singletonList(nr);
}
- return new NetworkRequestInfo(requests, nr, msgr, binder, callingAttributionTag);
+ return new NetworkRequestInfo(
+ requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
}
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
@@ -5739,8 +5734,9 @@
@Override
public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, IBinder binder, @NonNull String callingPackageName,
- @Nullable String callingAttributionTag) {
+ Messenger messenger, IBinder binder,
+ @NetworkCallback.Flag int callbackFlags,
+ @NonNull String callingPackageName, @NonNull String callingAttributionTag) {
final int callingUid = mDeps.getCallingUid();
if (!hasWifiNetworkListenPermission(networkCapabilities)) {
enforceAccessPermission();
@@ -5761,7 +5757,8 @@
NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
NetworkRequest.Type.LISTEN);
NetworkRequestInfo nri =
- new NetworkRequestInfo(networkRequest, messenger, binder, callingAttributionTag);
+ new NetworkRequestInfo(networkRequest, messenger, binder, callbackFlags,
+ callingAttributionTag);
if (VDBG) log("listenForNetwork for " + nri);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -5830,8 +5827,7 @@
public int registerNetworkProvider(Messenger messenger, String name) {
enforceNetworkFactoryOrSettingsPermission();
NetworkProviderInfo npi = new NetworkProviderInfo(name, messenger,
- null /* asyncChannel */, nextNetworkProviderId(),
- () -> unregisterNetworkProvider(messenger));
+ nextNetworkProviderId(), () -> unregisterNetworkProvider(messenger));
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_PROVIDER, npi));
return npi.providerId;
}
@@ -7090,6 +7086,8 @@
if (notificationType != ConnectivityManager.CALLBACK_UNAVAIL) {
putParcelable(bundle, networkAgent.network);
}
+ final boolean includeLocationSensitiveInfo =
+ (nri.mCallbackFlags & NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) != 0;
switch (notificationType) {
case ConnectivityManager.CALLBACK_AVAILABLE: {
final NetworkCapabilities nc =
@@ -7098,7 +7096,8 @@
putParcelable(
bundle,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- nc, nri.mUid, nrForCallback.getRequestorPackageName(),
+ nc, includeLocationSensitiveInfo, nri.mUid,
+ nrForCallback.getRequestorPackageName(),
nri.mCallingAttributionTag));
putParcelable(bundle, linkPropertiesRestrictedForCallerPermissions(
networkAgent.linkProperties, nri.mPid, nri.mUid));
@@ -7118,7 +7117,8 @@
putParcelable(
bundle,
createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- netCap, nri.mUid, nrForCallback.getRequestorPackageName(),
+ netCap, includeLocationSensitiveInfo, nri.mUid,
+ nrForCallback.getRequestorPackageName(),
nri.mCallingAttributionTag));
break;
}
diff --git a/services/core/java/com/android/server/NetIdManager.java b/services/core/java/com/android/server/NetIdManager.java
index 097fb3a..61925c8 100644
--- a/services/core/java/com/android/server/NetIdManager.java
+++ b/services/core/java/com/android/server/NetIdManager.java
@@ -17,6 +17,7 @@
package com.android.server;
import android.annotation.NonNull;
+import android.net.ConnectivityManager;
import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
@@ -31,7 +32,7 @@
// Sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
public static final int MIN_NET_ID = 100; // some reserved marks
// Top IDs reserved by IpSecService
- public static final int MAX_NET_ID = 65535 - IpSecService.TUN_INTF_NETID_RANGE;
+ public static final int MAX_NET_ID = ConnectivityManager.getIpSecNetIdRange().getLower() - 1;
@GuardedBy("mNetIdInUse")
private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 9411e33..488677a 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -31,14 +31,17 @@
import static com.android.net.module.util.CollectionUtils.toIntArray;
import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManagerInternal;
import android.net.INetd;
import android.net.UidRange;
+import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -54,7 +57,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.CollectionUtils;
-import com.android.server.LocalServices;
import java.util.ArrayList;
import java.util.HashMap;
@@ -71,7 +73,7 @@
*
* @hide
*/
-public class PermissionMonitor implements PackageManagerInternal.PackageListObserver {
+public class PermissionMonitor {
private static final String TAG = "PermissionMonitor";
private static final boolean DBG = true;
protected static final Boolean SYSTEM = Boolean.TRUE;
@@ -83,6 +85,7 @@
private final SystemConfigManager mSystemConfigManager;
private final INetd mNetd;
private final Dependencies mDeps;
+ private final Context mContext;
@GuardedBy("this")
private final Set<UserHandle> mUsers = new HashSet<>();
@@ -102,6 +105,25 @@
@GuardedBy("this")
private final Set<Integer> mAllApps = new HashSet<>();
+ private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ final Uri packageData = intent.getData();
+ final String packageName =
+ packageData != null ? packageData.getSchemeSpecificPart() : null;
+
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+ onPackageAdded(packageName, uid);
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ onPackageRemoved(packageName, uid);
+ } else {
+ Log.wtf(TAG, "received unexpected intent: " + action);
+ }
+ }
+ };
+
/**
* Dependencies of PermissionMonitor, for injection in tests.
*/
@@ -127,6 +149,7 @@
mSystemConfigManager = context.getSystemService(SystemConfigManager.class);
mNetd = netd;
mDeps = deps;
+ mContext = context;
}
// Intended to be called only once at startup, after the system is ready. Installs a broadcast
@@ -134,12 +157,14 @@
public synchronized void startMonitoring() {
log("Monitoring");
- PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
- if (pmi != null) {
- pmi.getPackageList(this);
- } else {
- loge("failed to get the PackageManagerInternal service");
- }
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter.addDataScheme("package");
+ mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */).registerReceiver(
+ mIntentReceiver, intentFilter, null /* broadcastPermission */,
+ null /* scheduler */);
+
List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS
| MATCH_ANY_USER);
if (apps == null) {
@@ -347,9 +372,10 @@
*
* @hide
*/
- @Override
public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
- sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+ // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
+ // using appId instead of uid actually
+ sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
// If multiple packages share a UID (cf: android:sharedUserId) and ask for different
// permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
@@ -384,9 +410,10 @@
*
* @hide
*/
- @Override
public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
- sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+ // TODO: Netd is using appId for checking traffic permission. Correct the methods that are
+ // using appId instead of uid actually
+ sendPackagePermissionsForUid(UserHandle.getAppId(uid), getPermissionForUid(uid));
// If the newly-removed package falls within some VPN's uid range, update Netd with it.
// This needs to happen before the mApps update below, since removeBypassingUids() depends
@@ -432,19 +459,6 @@
}
}
- /**
- * Called when a package is changed.
- *
- * @param packageName The name of the changed package.
- * @param uid The uid of the changed package.
- *
- * @hide
- */
- @Override
- public synchronized void onPackageChanged(@NonNull final String packageName, final int uid) {
- sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
- }
-
private static int getNetdPermissionMask(String[] requestedPermissions,
int[] requestedPermissionsFlags) {
int permissions = 0;
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 6a09b02..6fc605e 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -220,7 +220,7 @@
// register callback
when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
- any(), nullable(String.class))).thenReturn(request);
+ anyInt(), any(), nullable(String.class))).thenReturn(request);
manager.requestNetwork(request, callback, handler);
// callback triggers
@@ -248,7 +248,7 @@
// register callback
when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
- any(), nullable(String.class))).thenReturn(req1);
+ anyInt(), any(), nullable(String.class))).thenReturn(req1);
manager.requestNetwork(req1, callback, handler);
// callback triggers
@@ -266,7 +266,7 @@
// callback can be registered again
when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
- any(), nullable(String.class))).thenReturn(req2);
+ anyInt(), any(), nullable(String.class))).thenReturn(req2);
manager.requestNetwork(req2, callback, handler);
// callback triggers
@@ -289,8 +289,8 @@
info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
when(mCtx.getApplicationInfo()).thenReturn(info);
- when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), any(),
- nullable(String.class))).thenReturn(request);
+ when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), anyInt(),
+ any(), nullable(String.class))).thenReturn(request);
Handler handler = new Handler(Looper.getMainLooper());
manager.requestNetwork(request, callback, handler);
@@ -358,34 +358,34 @@
manager.requestNetwork(request, callback);
verify(mService).requestNetwork(eq(request.networkCapabilities),
- eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
// Verify that register network callback does not calls requestNetwork at all.
manager.registerNetworkCallback(request, callback);
- verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(),
+ verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(),
anyInt(), any(), any());
- verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(),
+ verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
manager.registerDefaultNetworkCallback(callback);
verify(mService).requestNetwork(eq(null),
- eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
- eq(testPkgName), eq(testAttributionTag));
- reset(mService);
-
- manager.requestBackgroundNetwork(request, null, callback);
- verify(mService).requestNetwork(eq(request.networkCapabilities),
- eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
+ manager.requestBackgroundNetwork(request, handler, callback);
+ verify(mService).requestNetwork(eq(request.networkCapabilities),
+ eq(BACKGROUND_REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
+ eq(testPkgName), eq(testAttributionTag));
+ reset(mService);
+
manager.registerSystemDefaultNetworkCallback(callback, handler);
verify(mService).requestNetwork(eq(null),
- eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(TRACK_SYSTEM_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE), anyInt(),
eq(testPkgName), eq(testAttributionTag));
reset(mService);
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 15a7b91..2c8c8a6 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1454,6 +1454,8 @@
applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
.thenReturn(applicationInfo);
+ when(mPackageManager.getTargetSdkVersion(anyString()))
+ .thenReturn(applicationInfo.targetSdkVersion);
when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
// InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
@@ -3749,8 +3751,8 @@
networkCapabilities.addTransportType(TRANSPORT_WIFI)
.setNetworkSpecifier(new MatchAllNetworkSpecifier());
mService.requestNetwork(networkCapabilities, NetworkRequest.Type.REQUEST.ordinal(),
- null, 0, null, ConnectivityManager.TYPE_WIFI, mContext.getPackageName(),
- getAttributionTag());
+ null, 0, null, ConnectivityManager.TYPE_WIFI, NetworkCallback.FLAG_NONE,
+ mContext.getPackageName(), getAttributionTag());
});
class NonParcelableSpecifier extends NetworkSpecifier {
@@ -4027,7 +4029,8 @@
grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid());
final TestNetworkCallback cellBgCallback = new TestNetworkCallback();
mCm.requestBackgroundNetwork(new NetworkRequest.Builder()
- .addTransportType(TRANSPORT_CELLULAR).build(), null, cellBgCallback);
+ .addTransportType(TRANSPORT_CELLULAR).build(),
+ mCsHandlerThread.getThreadHandler(), cellBgCallback);
// Make callbacks for monitoring.
final NetworkRequest request = new NetworkRequest.Builder().build();
@@ -8755,6 +8758,7 @@
applicationInfo.targetSdkVersion = targetSdk;
when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
.thenReturn(applicationInfo);
+ when(mPackageManager.getTargetSdkVersion(any())).thenReturn(targetSdk);
when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(locationToggle);
@@ -8769,102 +8773,183 @@
}
}
- private int getOwnerUidNetCapsForCallerPermission(int ownerUid, int callerUid) {
+ private int getOwnerUidNetCapsPermission(int ownerUid, int callerUid,
+ boolean includeLocationSensitiveInfo) {
final NetworkCapabilities netCap = new NetworkCapabilities().setOwnerUid(ownerUid);
return mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- netCap, callerUid, mContext.getPackageName(), getAttributionTag()).getOwnerUid();
+ netCap, includeLocationSensitiveInfo, callerUid,
+ mContext.getPackageName(), getAttributionTag())
+ .getOwnerUid();
}
- private void verifyWifiInfoCopyNetCapsForCallerPermission(
- int callerUid, boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
+ private void verifyWifiInfoCopyNetCapsPermission(
+ int callerUid, boolean includeLocationSensitiveInfo,
+ boolean shouldMakeCopyWithLocationSensitiveFieldsParcelable) {
final WifiInfo wifiInfo = mock(WifiInfo.class);
when(wifiInfo.hasLocationSensitiveFields()).thenReturn(true);
final NetworkCapabilities netCap = new NetworkCapabilities().setTransportInfo(wifiInfo);
mService.createWithLocationInfoSanitizedIfNecessaryWhenParceled(
- netCap, callerUid, mContext.getPackageName(), getAttributionTag());
+ netCap, includeLocationSensitiveInfo, callerUid,
+ mContext.getPackageName(), getAttributionTag());
verify(wifiInfo).makeCopy(eq(shouldMakeCopyWithLocationSensitiveFieldsParcelable));
}
+ private void verifyOwnerUidAndWifiInfoNetCapsPermission(
+ boolean shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag,
+ boolean shouldInclLocationSensitiveOwnerUidWithIncludeFlag,
+ boolean shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag,
+ boolean shouldInclLocationSensitiveWifiInfoWithIncludeFlag) {
+ final int myUid = Process.myUid();
+
+ final int expectedOwnerUidWithoutIncludeFlag =
+ shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag
+ ? Process.myUid() : INVALID_UID;
+ assertEquals(expectedOwnerUidWithoutIncludeFlag, getOwnerUidNetCapsPermission(
+ myUid, myUid, false /* includeLocationSensitiveInfo */));
+
+ final int expectedOwnerUidWithIncludeFlag =
+ shouldInclLocationSensitiveOwnerUidWithIncludeFlag ? myUid : INVALID_UID;
+ assertEquals(expectedOwnerUidWithIncludeFlag, getOwnerUidNetCapsPermission(
+ myUid, myUid, true /* includeLocationSensitiveInfo */));
+
+ verifyWifiInfoCopyNetCapsPermission(myUid,
+ false, /* includeLocationSensitiveInfo */
+ shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag);
+
+ verifyWifiInfoCopyNetCapsPermission(myUid,
+ true, /* includeLocationSensitiveInfo */
+ shouldInclLocationSensitiveWifiInfoWithIncludeFlag);
+
+ }
+
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithFineLocationAfterQ()
+ public void testCreateWithLocationInfoSanitizedWithFineLocationAfterQ()
throws Exception {
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
- final int myUid = Process.myUid();
- assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we include owner uid even if the request asks to remove it since the
+ // app has necessary permissions and targetSdk < S.
+ true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithCoarseLocationPreQ()
+ public void testCreateWithLocationInfoSanitizedWithFineLocationPreSWithAndWithoutCallbackFlag()
+ throws Exception {
+ setupLocationPermissions(Build.VERSION_CODES.R, true, AppOpsManager.OPSTR_FINE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we include owner uid even if the request asks to remove it since the
+ // app has necessary permissions and targetSdk < S.
+ true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
+ }
+
+ @Test
+ public void
+ testCreateWithLocationInfoSanitizedWithFineLocationAfterSWithAndWithoutCallbackFlag()
+ throws Exception {
+ setupLocationPermissions(Build.VERSION_CODES.S, true, AppOpsManager.OPSTR_FINE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we owner UID if the request asks us to remove it even if the app
+ // has necessary permissions since targetSdk >= S.
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
+ }
+
+ @Test
+ public void testCreateWithLocationInfoSanitizedWithCoarseLocationPreQ()
throws Exception {
setupLocationPermissions(Build.VERSION_CODES.P, true, AppOpsManager.OPSTR_COARSE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION);
- final int myUid = Process.myUid();
- assertEquals(myUid, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ // Ensure that we owner UID if the request asks us to remove it even if the app
+ // has necessary permissions since targetSdk >= S.
+ true, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ true, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ // Ensure that we remove location info if the request asks to remove it even if the
+ // app has necessary permissions.
+ true /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedLocationOff() throws Exception {
+ public void testCreateWithLocationInfoSanitizedLocationOff() throws Exception {
// Test that even with fine location permission, and UIDs matching, the UID is sanitized.
setupLocationPermissions(Build.VERSION_CODES.Q, false, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
- final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWrongUid() throws Exception {
+ public void testCreateWithLocationInfoSanitizedWrongUid() throws Exception {
// Test that even with fine location permission, not being the owner leads to sanitization.
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION);
final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid + 1, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- true /* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ assertEquals(Process.INVALID_UID,
+ getOwnerUidNetCapsPermission(myUid + 1, myUid,
+ true /* includeLocationSensitiveInfo */));
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithCoarseLocationAfterQ()
+ public void testCreateWithLocationInfoSanitizedWithCoarseLocationAfterQ()
throws Exception {
// Test that not having fine location permission leads to sanitization.
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_COARSE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION);
- // Test that without the location permission, the owner field is sanitized.
- final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
@Test
- public void testCreateForCallerWithLocationInfoSanitizedWithoutLocationPermission()
+ public void testCreateWithLocationInfoSanitizedWithoutLocationPermission()
throws Exception {
+ // Test that not having fine location permission leads to sanitization.
setupLocationPermissions(Build.VERSION_CODES.Q, true, null /* op */, null /* perm */);
- // Test that without the location permission, the owner field is sanitized.
- final int myUid = Process.myUid();
- assertEquals(Process.INVALID_UID, getOwnerUidNetCapsForCallerPermission(myUid, myUid));
-
- verifyWifiInfoCopyNetCapsForCallerPermission(myUid,
- false/* shouldMakeCopyWithLocationSensitiveFieldsParcelable */);
+ verifyOwnerUidAndWifiInfoNetCapsPermission(
+ false, /* shouldInclLocationSensitiveOwnerUidWithoutIncludeFlag */
+ false, /* shouldInclLocationSensitiveOwnerUidWithIncludeFlag */
+ false, /* shouldInclLocationSensitiveWifiInfoWithoutIncludeFlag */
+ false /* shouldInclLocationSensitiveWifiInfoWithIncludeFlag */
+ );
}
private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
@@ -9455,8 +9540,8 @@
assertThrows("Expect throws for invalid request type " + reqTypeInt,
IllegalArgumentException.class,
() -> mService.requestNetwork(nc, reqTypeInt, null, 0, null,
- ConnectivityManager.TYPE_NONE, mContext.getPackageName(),
- getAttributionTag())
+ ConnectivityManager.TYPE_NONE, NetworkCallback.FLAG_NONE,
+ mContext.getPackageName(), getAttributionTag())
);
}
}
@@ -11026,4 +11111,12 @@
verifyNoNetwork();
mCm.unregisterNetworkCallback(cellCb);
}
-}
\ No newline at end of file
+
+ @Test
+ public void testRegisterBestMatchingNetworkCallback() throws Exception {
+ final NetworkRequest request = new NetworkRequest.Builder().build();
+ assertThrows(UnsupportedOperationException.class,
+ () -> mCm.registerBestMatchingNetworkCallback(request, new NetworkCallback(),
+ mCsHandlerThread.getThreadHandler()));
+ }
+}
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index f97eabf..6232423 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -35,6 +35,7 @@
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.IpSecAlgorithm;
import android.net.IpSecConfig;
@@ -47,6 +48,7 @@
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructStat;
+import android.util.Range;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -647,9 +649,9 @@
@Test
public void testReserveNetId() {
- int start = mIpSecService.TUN_INTF_NETID_START;
- for (int i = 0; i < mIpSecService.TUN_INTF_NETID_RANGE; i++) {
- assertEquals(start + i, mIpSecService.reserveNetId());
+ final Range<Integer> netIdRange = ConnectivityManager.getIpSecNetIdRange();
+ for (int netId = netIdRange.getLower(); netId <= netIdRange.getUpper(); netId++) {
+ assertEquals(netId, mIpSecService.reserveNetId());
}
// Check that resource exhaustion triggers an exception
@@ -661,7 +663,7 @@
// Now release one and try again
int releasedNetId =
- mIpSecService.TUN_INTF_NETID_START + mIpSecService.TUN_INTF_NETID_RANGE / 2;
+ netIdRange.getLower() + (netIdRange.getUpper() - netIdRange.getLower()) / 2;
mIpSecService.releaseNetId(releasedNetId);
assertEquals(releasedNetId, mIpSecService.reserveNetId());
}
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index e4e24b4..fec5ef3 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -48,18 +48,22 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.net.INetd;
import android.net.UidRange;
+import android.net.Uri;
import android.os.Build;
import android.os.SystemConfigManager;
import android.os.UserHandle;
@@ -70,12 +74,11 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.server.LocalServices;
-import com.android.server.pm.PackageList;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.AdditionalAnswers;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
@@ -112,7 +115,6 @@
@Mock private Context mContext;
@Mock private PackageManager mPackageManager;
@Mock private INetd mNetdService;
- @Mock private PackageManagerInternal mMockPmi;
@Mock private UserManager mUserManager;
@Mock private PermissionMonitor.Dependencies mDeps;
@Mock private SystemConfigManager mSystemConfigManager;
@@ -131,16 +133,14 @@
when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE))
.thenReturn(mSystemConfigManager);
when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
+ final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext));
+ doReturn(UserHandle.ALL).when(asUserCtx).getUser();
+ when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx);
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
- LocalServices.removeServiceForTest(PackageManagerInternal.class);
- LocalServices.addService(PackageManagerInternal.class, mMockPmi);
- when(mMockPmi.getPackageList(any())).thenReturn(new PackageList(new ArrayList<String>(),
- /* observer */ null));
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null);
mPermissionMonitor.startMonitoring();
- verify(mMockPmi).getPackageList(mPermissionMonitor);
}
private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
@@ -770,4 +770,32 @@
INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
new int[]{ MOCK_UID2 });
}
+
+ @Test
+ public void testIntentReceiver() throws Exception {
+ final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+ verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(), any(), any(), any());
+ final BroadcastReceiver receiver = receiverCaptor.getValue();
+
+ // Verify receiving PACKAGE_ADDED intent.
+ final Intent addedIntent = new Intent(Intent.ACTION_PACKAGE_ADDED,
+ Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
+ addedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
+ setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1,
+ new String[] { INTERNET, UPDATE_DEVICE_STATS });
+ receiver.onReceive(mContext, addedIntent);
+ mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[] { MOCK_UID1 });
+
+ // Verify receiving PACKAGE_REMOVED intent.
+ when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(null);
+ final Intent removedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED,
+ Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
+ removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
+ receiver.onReceive(mContext, removedIntent);
+ mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[] { MOCK_UID1 });
+ }
+
}