Merge "Add NETWORK_AIRPLANE_MODE permission"
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a5bc408..fbd90bd 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -50,6 +50,7 @@
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
+import android.os.SystemClock;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -57,7 +58,6 @@
import android.util.Log;
import android.util.SparseIntArray;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol;
@@ -802,6 +802,7 @@
private INetworkManagementService mNMService;
private INetworkPolicyManager mNPManager;
+ private TetheringManager mTetheringManager;
/**
* Tests if a given integer represents a valid network type.
@@ -1006,7 +1007,7 @@
*
* @hide
*/
- @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
+ @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
@Nullable
public Network getActiveNetworkForUid(int uid) {
return getActiveNetworkForUid(uid, false);
@@ -1135,7 +1136,7 @@
*
* {@hide}
*/
- @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
+ @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
@UnsupportedAppUsage
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
return getActiveNetworkInfoForUid(uid, false);
@@ -1370,10 +1371,14 @@
* The system network validation may be using different strategies to detect captive portals,
* so this method does not necessarily return a URL used by the system. It only returns a URL
* that may be relevant for other components trying to detect captive portals.
+ *
* @hide
+ * @deprecated This API returns URL which is not guaranteed to be one of the URLs used by the
+ * system.
*/
+ @Deprecated
@SystemApi
- @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS)
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public String getCaptivePortalServerUrl() {
try {
return mService.getCaptivePortalServerUrl();
@@ -2335,6 +2340,28 @@
return getInstanceOrNull();
}
+ private static final int TETHERING_TIMEOUT_MS = 60_000;
+ private final Object mTetheringLock = new Object();
+
+ private TetheringManager getTetheringManager() {
+ synchronized (mTetheringLock) {
+ if (mTetheringManager != null) {
+ return mTetheringManager;
+ }
+ final long before = System.currentTimeMillis();
+ while ((mTetheringManager = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE)) == null) {
+ if (System.currentTimeMillis() - before > TETHERING_TIMEOUT_MS) {
+ Log.e(TAG, "Timeout waiting tethering service not ready yet");
+ throw new IllegalStateException("No tethering service yet");
+ }
+ SystemClock.sleep(100);
+ }
+
+ return mTetheringManager;
+ }
+ }
+
/**
* Get the set of tetherable, available interfaces. This list is limited by
* device configuration and current interface existence.
@@ -2346,11 +2373,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableIfaces() {
- try {
- return mService.getTetherableIfaces();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableIfaces();
}
/**
@@ -2363,11 +2386,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetheredIfaces() {
- try {
- return mService.getTetheredIfaces();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetheredIfaces();
}
/**
@@ -2386,11 +2405,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetheringErroredIfaces() {
- try {
- return mService.getTetheringErroredIfaces();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetheringErroredIfaces();
}
/**
@@ -2399,12 +2414,9 @@
* @return an array of 0 or more {@code String} of tethered dhcp ranges.
* {@hide}
*/
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public String[] getTetheredDhcpRanges() {
- try {
- return mService.getTetheredDhcpRanges();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetheredDhcpRanges();
}
/**
@@ -2433,13 +2445,7 @@
*/
@UnsupportedAppUsage
public int tether(String iface) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "tether caller:" + pkgName);
- return mService.tether(iface, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().tether(iface);
}
/**
@@ -2462,13 +2468,7 @@
*/
@UnsupportedAppUsage
public int untether(String iface) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "untether caller:" + pkgName);
- return mService.untether(iface, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().untether(iface);
}
/**
@@ -2493,16 +2493,7 @@
@RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
android.Manifest.permission.WRITE_SETTINGS})
public boolean isTetheringSupported() {
- String pkgName = mContext.getOpPackageName();
- try {
- return mService.isTetheringSupported(pkgName);
- } catch (SecurityException e) {
- // This API is not available to this caller, but for backward-compatibility
- // this will just return false instead of throwing.
- return false;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().isTetheringSupported();
}
/**
@@ -2571,14 +2562,7 @@
}
};
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "startTethering caller:" + pkgName);
- mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
- } catch (RemoteException e) {
- Log.e(TAG, "Exception trying to start tethering.", e);
- wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
- }
+ getTetheringManager().startTethering(type, wrappedCallback, showProvisioningUi);
}
/**
@@ -2594,13 +2578,7 @@
@SystemApi
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
public void stopTethering(int type) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "stopTethering caller:" + pkgName);
- mService.stopTethering(type, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ getTetheringManager().stopTethering(type);
}
/**
@@ -2622,10 +2600,6 @@
public void onUpstreamChanged(@Nullable Network network) {}
}
- @GuardedBy("mTetheringEventCallbacks")
- private final ArrayMap<OnTetheringEventCallback, ITetheringEventCallback>
- mTetheringEventCallbacks = new ArrayMap<>();
-
/**
* Start listening to tethering change events. Any new added callback will receive the last
* tethering status right away. If callback is registered when tethering has no upstream or
@@ -2643,27 +2617,7 @@
@NonNull final OnTetheringEventCallback callback) {
Preconditions.checkNotNull(callback, "OnTetheringEventCallback cannot be null.");
- synchronized (mTetheringEventCallbacks) {
- Preconditions.checkArgument(!mTetheringEventCallbacks.containsKey(callback),
- "callback was already registered.");
- ITetheringEventCallback remoteCallback = new ITetheringEventCallback.Stub() {
- @Override
- public void onUpstreamChanged(Network network) throws RemoteException {
- Binder.withCleanCallingIdentity(() ->
- executor.execute(() -> {
- callback.onUpstreamChanged(network);
- }));
- }
- };
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "registerTetheringUpstreamCallback:" + pkgName);
- mService.registerTetheringEventCallback(remoteCallback, pkgName);
- mTetheringEventCallbacks.put(callback, remoteCallback);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ getTetheringManager().registerTetheringEventCallback(executor, callback);
}
/**
@@ -2677,17 +2631,7 @@
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
public void unregisterTetheringEventCallback(
@NonNull final OnTetheringEventCallback callback) {
- synchronized (mTetheringEventCallbacks) {
- ITetheringEventCallback remoteCallback = mTetheringEventCallbacks.remove(callback);
- Preconditions.checkNotNull(remoteCallback, "callback was not registered.");
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "unregisterTetheringEventCallback:" + pkgName);
- mService.unregisterTetheringEventCallback(remoteCallback, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ getTetheringManager().unregisterTetheringEventCallback(callback);
}
@@ -2704,11 +2648,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableUsbRegexs() {
- try {
- return mService.getTetherableUsbRegexs();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableUsbRegexs();
}
/**
@@ -2724,11 +2664,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableWifiRegexs() {
- try {
- return mService.getTetherableWifiRegexs();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableWifiRegexs();
}
/**
@@ -2744,11 +2680,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public String[] getTetherableBluetoothRegexs() {
- try {
- return mService.getTetherableBluetoothRegexs();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getTetherableBluetoothRegexs();
}
/**
@@ -2770,13 +2702,7 @@
*/
@UnsupportedAppUsage
public int setUsbTethering(boolean enable) {
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "setUsbTethering caller:" + pkgName);
- return mService.setUsbTethering(enable, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().setUsbTethering(enable);
}
/** {@hide} */
@@ -2824,11 +2750,7 @@
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
@UnsupportedAppUsage
public int getLastTetherError(String iface) {
- try {
- return mService.getLastTetherError(iface);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return getTetheringManager().getLastTetherError(iface);
}
/** @hide */
@@ -2894,14 +2816,8 @@
}
};
- try {
- String pkgName = mContext.getOpPackageName();
- Log.i(TAG, "getLatestTetheringEntitlementResult:" + pkgName);
- mService.getLatestTetheringEntitlementResult(type, wrappedListener,
- showEntitlementUi, pkgName);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ getTetheringManager().requestLatestTetheringEntitlementResult(type, wrappedListener,
+ showEntitlementUi);
}
/**
@@ -2978,7 +2894,7 @@
* HTTP proxy. A {@code null} value will clear the global HTTP proxy.
* @hide
*/
- @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
+ @RequiresPermission(android.Manifest.permission.NETWORK_STACK)
public void setGlobalProxy(ProxyInfo p) {
try {
mService.setGlobalProxy(p);
@@ -3123,6 +3039,7 @@
* Get the mobile provisioning url.
* {@hide}
*/
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public String getMobileProvisioningUrl() {
try {
return mService.getMobileProvisioningUrl();
@@ -3170,6 +3087,7 @@
/** {@hide} - returns the factory serial number */
@UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
public int registerNetworkFactory(Messenger messenger, String name) {
try {
return mService.registerNetworkFactory(messenger, name);
@@ -3180,6 +3098,7 @@
/** {@hide} */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
public void unregisterNetworkFactory(Messenger messenger) {
try {
mService.unregisterNetworkFactory(messenger);
@@ -3197,6 +3116,7 @@
* Register a NetworkAgent with ConnectivityService.
* @return NetID corresponding to NetworkAgent.
*/
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkMisc misc) {
return registerNetworkAgent(messenger, ni, lp, nc, score, misc,
@@ -3208,6 +3128,7 @@
* Register a NetworkAgent with ConnectivityService.
* @return NetID corresponding to NetworkAgent.
*/
+ @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkMisc misc, int factorySerialNumber) {
try {
@@ -4202,7 +4123,7 @@
*
* @hide
*/
- @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public void startCaptivePortalApp(Network network) {
try {
mService.startCaptivePortalApp(network);
@@ -4318,9 +4239,11 @@
* Resets all connectivity manager settings back to factory defaults.
* @hide
*/
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
public void factoryReset() {
try {
mService.factoryReset();
+ getTetheringManager().stopAllTethering();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 5f662f9..09c02ef 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -19,7 +19,6 @@
import android.app.PendingIntent;
import android.net.ConnectionInfo;
import android.net.LinkProperties;
-import android.net.ITetheringEventCallback;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
@@ -78,41 +77,31 @@
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
- int tether(String iface, String callerPkg);
-
- int untether(String iface, String callerPkg);
-
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative")
int getLastTetherError(String iface);
- boolean isTetheringSupported(String callerPkg);
-
- void startTethering(int type, in ResultReceiver receiver, boolean showProvisioningUi,
- String callerPkg);
-
- void stopTethering(int type, String callerPkg);
-
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetherableIfaces} as alternative")
String[] getTetherableIfaces();
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetheredIfaces} as alternative")
String[] getTetheredIfaces();
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetheringErroredIfaces} "
+ + "as Alternative")
String[] getTetheringErroredIfaces();
- String[] getTetheredDhcpRanges();
-
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetherableUsbRegexs} as alternative")
String[] getTetherableUsbRegexs();
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = 29,
+ publicAlternatives = "Use {@code TetheringManager#getTetherableWifiRegexs} as alternative")
String[] getTetherableWifiRegexs();
- String[] getTetherableBluetoothRegexs();
-
- int setUsbTethering(boolean enable, String callerPkg);
-
@UnsupportedAppUsage(maxTargetSdk = 28)
void reportInetCondition(int networkType, int percentage);
@@ -217,11 +206,5 @@
boolean isCallerCurrentAlwaysOnVpnApp();
boolean isCallerCurrentAlwaysOnVpnLockdownApp();
- void getLatestTetheringEntitlementResult(int type, in ResultReceiver receiver,
- boolean showEntitlementUi, String callerPkg);
-
- void registerTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
- void unregisterTetheringEventCallback(ITetheringEventCallback callback, String callerPkg);
-
IBinder startOrGetTestNetworkService();
}
diff --git a/core/java/android/net/InvalidPacketException.java b/core/java/android/net/InvalidPacketException.java
new file mode 100644
index 0000000..909998d
--- /dev/null
+++ b/core/java/android/net/InvalidPacketException.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 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.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Thrown when a packet is invalid.
+ * @hide
+ */
+@SystemApi
+public class InvalidPacketException extends Exception {
+ public final int error;
+
+ // Must match SocketKeepalive#ERROR_INVALID_IP_ADDRESS.
+ /** Invalid IP address. */
+ public static final int ERROR_INVALID_IP_ADDRESS = -21;
+
+ // Must match SocketKeepalive#ERROR_INVALID_PORT.
+ /** Invalid port number. */
+ public static final int ERROR_INVALID_PORT = -22;
+
+ // Must match SocketKeepalive#ERROR_INVALID_LENGTH.
+ /** Invalid packet length. */
+ public static final int ERROR_INVALID_LENGTH = -23;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "ERROR_" }, value = {
+ ERROR_INVALID_IP_ADDRESS,
+ ERROR_INVALID_PORT,
+ ERROR_INVALID_LENGTH
+ })
+ public @interface ErrorCode {}
+
+ /**
+ * This packet is invalid.
+ * See the error code for details.
+ */
+ public InvalidPacketException(@ErrorCode final int error) {
+ this.error = error;
+ }
+}
diff --git a/core/java/android/net/KeepalivePacketData.java b/core/java/android/net/KeepalivePacketData.java
index 9b8b732..2b8b7e6 100644
--- a/core/java/android/net/KeepalivePacketData.java
+++ b/core/java/android/net/KeepalivePacketData.java
@@ -16,13 +16,13 @@
package android.net;
-import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
-import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
+import static android.net.InvalidPacketException.ERROR_INVALID_IP_ADDRESS;
+import static android.net.InvalidPacketException.ERROR_INVALID_PORT;
-import android.net.SocketKeepalive.InvalidPacketException;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.net.util.IpUtils;
import android.os.Parcel;
-import android.os.Parcelable;
import android.util.Log;
import java.net.InetAddress;
@@ -33,13 +33,16 @@
*
* @hide
*/
-public class KeepalivePacketData implements Parcelable {
+@SystemApi
+public class KeepalivePacketData {
private static final String TAG = "KeepalivePacketData";
/** Source IP address */
+ @NonNull
public final InetAddress srcAddress;
/** Destination IP address */
+ @NonNull
public final InetAddress dstAddress;
/** Source port */
@@ -51,13 +54,14 @@
/** Packet data. A raw byte string of packet data, not including the link-layer header. */
private final byte[] mPacket;
- protected static final int IPV4_HEADER_LENGTH = 20;
- protected static final int UDP_HEADER_LENGTH = 8;
-
// This should only be constructed via static factory methods, such as
- // nattKeepalivePacket
- protected KeepalivePacketData(InetAddress srcAddress, int srcPort,
- InetAddress dstAddress, int dstPort, byte[] data) throws InvalidPacketException {
+ // nattKeepalivePacket.
+ /**
+ * A holding class for data necessary to build a keepalive packet.
+ */
+ protected KeepalivePacketData(@NonNull InetAddress srcAddress, int srcPort,
+ @NonNull InetAddress dstAddress, int dstPort,
+ @NonNull byte[] data) throws InvalidPacketException {
this.srcAddress = srcAddress;
this.dstAddress = dstAddress;
this.srcPort = srcPort;
@@ -78,16 +82,12 @@
}
}
+ @NonNull
public byte[] getPacket() {
return mPacket.clone();
}
- /* Parcelable Implementation */
- public int describeContents() {
- return 0;
- }
-
- /** Write to parcel */
+ /** @hide */
public void writeToParcel(Parcel out, int flags) {
out.writeString(srcAddress.getHostAddress());
out.writeString(dstAddress.getHostAddress());
@@ -96,6 +96,7 @@
out.writeByteArray(mPacket);
}
+ /** @hide */
protected KeepalivePacketData(Parcel in) {
srcAddress = NetworkUtils.numericToInetAddress(in.readString());
dstAddress = NetworkUtils.numericToInetAddress(in.readString());
@@ -103,17 +104,4 @@
dstPort = in.readInt();
mPacket = in.createByteArray();
}
-
- /** Parcelable Creator */
- public static final @android.annotation.NonNull Parcelable.Creator<KeepalivePacketData> CREATOR =
- new Parcelable.Creator<KeepalivePacketData>() {
- public KeepalivePacketData createFromParcel(Parcel in) {
- return new KeepalivePacketData(in);
- }
-
- public KeepalivePacketData[] newArray(int size) {
- return new KeepalivePacketData[size];
- }
- };
-
}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 0706e75..ed509cb 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -74,6 +74,8 @@
private static final int MIN_MTU_V6 = 1280;
private static final int MAX_MTU = 10000;
+ private static final int INET6_ADDR_LENGTH = 16;
+
// Stores the properties of links that are "stacked" above this link.
// Indexed by interface name to allow modification and to prevent duplicates being added.
private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<>();
@@ -227,7 +229,7 @@
/**
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public @NonNull List<String> getAllInterfaceNames() {
List<String> interfaceNames = new ArrayList<>(mStackedLinks.size() + 1);
if (mIfaceName != null) interfaceNames.add(mIfaceName);
@@ -247,7 +249,7 @@
* @return An unmodifiable {@link List} of {@link InetAddress} for this link.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public @NonNull List<InetAddress> getAddresses() {
final List<InetAddress> addresses = new ArrayList<>();
for (LinkAddress linkAddress : mLinkAddresses) {
@@ -342,8 +344,8 @@
* Returns all the addresses on this link and all the links stacked above it.
* @hide
*/
- @UnsupportedAppUsage
- public List<LinkAddress> getAllLinkAddresses() {
+ @SystemApi
+ public @NonNull List<LinkAddress> getAllLinkAddresses() {
List<LinkAddress> addresses = new ArrayList<>(mLinkAddresses);
for (LinkProperties stacked: mStackedLinks.values()) {
addresses.addAll(stacked.getAllLinkAddresses());
@@ -542,6 +544,7 @@
* @return true if the PCSCF server was added, false otherwise.
* @hide
*/
+ @SystemApi
public boolean addPcscfServer(@NonNull InetAddress pcscfServer) {
if (pcscfServer != null && !mPcscfs.contains(pcscfServer)) {
mPcscfs.add(pcscfServer);
@@ -729,7 +732,7 @@
* Returns all the routes on this link and all the links stacked above it.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public @NonNull List<RouteInfo> getAllRoutes() {
List<RouteInfo> routes = new ArrayList<>(mRoutes);
for (LinkProperties stacked: mStackedLinks.values()) {
@@ -762,10 +765,7 @@
* Returns the NAT64 prefix in use on this link, if any.
*
* @return the NAT64 prefix or {@code null}.
- * @hide
*/
- @SystemApi
- @TestApi
public @Nullable IpPrefix getNat64Prefix() {
return mNat64Prefix;
}
@@ -777,10 +777,7 @@
* 128-bit IPv6 address) are supported or {@code null} for no prefix.
*
* @param prefix the NAT64 prefix.
- * @hide
*/
- @SystemApi
- @TestApi
public void setNat64Prefix(@Nullable IpPrefix prefix) {
if (prefix != null && prefix.getPrefixLength() != 96) {
throw new IllegalArgumentException("Only 96-bit prefixes are supported: " + prefix);
@@ -1031,7 +1028,7 @@
* @return {@code true} if there is an IPv4 default route, {@code false} otherwise.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public boolean hasIpv4DefaultRoute() {
for (RouteInfo r : mRoutes) {
if (r.isIPv4Default()) {
@@ -1088,7 +1085,7 @@
* @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public boolean hasIpv4DnsServer() {
for (InetAddress ia : mDnses) {
if (ia instanceof Inet4Address) {
@@ -1116,7 +1113,7 @@
* @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public boolean hasIpv6DnsServer() {
for (InetAddress ia : mDnses) {
if (ia instanceof Inet6Address) {
@@ -1632,20 +1629,11 @@
dest.writeParcelable(linkAddress, flags);
}
- dest.writeInt(mDnses.size());
- for (InetAddress d : mDnses) {
- dest.writeByteArray(d.getAddress());
- }
- dest.writeInt(mValidatedPrivateDnses.size());
- for (InetAddress d : mValidatedPrivateDnses) {
- dest.writeByteArray(d.getAddress());
- }
+ writeAddresses(dest, mDnses);
+ writeAddresses(dest, mValidatedPrivateDnses);
dest.writeBoolean(mUsePrivateDns);
dest.writeString(mPrivateDnsServerName);
- dest.writeInt(mPcscfs.size());
- for (InetAddress d : mPcscfs) {
- dest.writeByteArray(d.getAddress());
- }
+ writeAddresses(dest, mPcscfs);
dest.writeString(mDomains);
dest.writeInt(mMtu);
dest.writeString(mTcpBufferSizes);
@@ -1668,6 +1656,35 @@
dest.writeBoolean(mWakeOnLanSupported);
}
+ private static void writeAddresses(@NonNull Parcel dest, @NonNull List<InetAddress> list) {
+ dest.writeInt(list.size());
+ for (InetAddress d : list) {
+ writeAddress(dest, d);
+ }
+ }
+
+ private static void writeAddress(@NonNull Parcel dest, @NonNull InetAddress addr) {
+ dest.writeByteArray(addr.getAddress());
+ if (addr instanceof Inet6Address) {
+ final Inet6Address v6Addr = (Inet6Address) addr;
+ final boolean hasScopeId = v6Addr.getScopeId() != 0;
+ dest.writeBoolean(hasScopeId);
+ if (hasScopeId) dest.writeInt(v6Addr.getScopeId());
+ }
+ }
+
+ @NonNull
+ private static InetAddress readAddress(@NonNull Parcel p) throws UnknownHostException {
+ final byte[] addr = p.createByteArray();
+ if (addr.length == INET6_ADDR_LENGTH) {
+ final boolean hasScopeId = p.readBoolean();
+ final int scopeId = hasScopeId ? p.readInt() : 0;
+ return Inet6Address.getByAddress(null /* host */, addr, scopeId);
+ }
+
+ return InetAddress.getByAddress(addr);
+ }
+
/**
* Implement the Parcelable interface.
*/
@@ -1687,14 +1704,13 @@
addressCount = in.readInt();
for (int i = 0; i < addressCount; i++) {
try {
- netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
+ netProp.addDnsServer(readAddress(in));
} catch (UnknownHostException e) { }
}
addressCount = in.readInt();
for (int i = 0; i < addressCount; i++) {
try {
- netProp.addValidatedPrivateDnsServer(
- InetAddress.getByAddress(in.createByteArray()));
+ netProp.addValidatedPrivateDnsServer(readAddress(in));
} catch (UnknownHostException e) { }
}
netProp.setUsePrivateDns(in.readBoolean());
@@ -1702,7 +1718,7 @@
addressCount = in.readInt();
for (int i = 0; i < addressCount; i++) {
try {
- netProp.addPcscfServer(InetAddress.getByAddress(in.createByteArray()));
+ netProp.addPcscfServer(readAddress(in));
} catch (UnknownHostException e) { }
}
netProp.setDomains(in.readString());
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
index a77c244..3fb52f1 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -19,7 +19,6 @@
import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
-import android.net.SocketKeepalive.InvalidPacketException;
import android.net.util.IpUtils;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +31,9 @@
/** @hide */
public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable {
+ private static final int IPV4_HEADER_LENGTH = 20;
+ private static final int UDP_HEADER_LENGTH = 8;
+
// This should only be constructed via static factory methods, such as
// nattKeepalivePacket
private NattKeepalivePacketData(InetAddress srcAddress, int srcPort,
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index 3f56def..c6c73fe 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -63,7 +63,7 @@
/**
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public final int netId;
// Objects used to perform per-network operations such as getSocketFactory
@@ -502,7 +502,7 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(NetworkProto.NET_ID, netId);
proto.end(token);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 88877e2..4cee5f3 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -60,10 +60,6 @@
// Set to true when private DNS is broken.
private boolean mPrivateDnsBroken;
- /**
- * @hide
- */
- @UnsupportedAppUsage
public NetworkCapabilities() {
clearAll();
mNetworkCapabilities = DEFAULT_CAPABILITIES;
@@ -78,7 +74,6 @@
/**
* Completely clears the contents of this object, removing even the capabilities that are set
* by default when the object is constructed.
- * @hide
*/
public void clearAll() {
mNetworkCapabilities = mTransportTypes = mUnwantedNetworkCapabilities = 0;
@@ -402,16 +397,15 @@
* Adds the given capability to this {@code NetworkCapability} instance.
* Multiple capabilities may be applied sequentially. Note that when searching
* for a network to satisfy a request, all capabilities requested must be satisfied.
- * <p>
- * If the given capability was previously added to the list of unwanted capabilities
- * then the capability will also be removed from the list of unwanted capabilities.
*
* @param capability the capability to be added.
* @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
*/
- @UnsupportedAppUsage
public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) {
+ // If the given capability was previously added to the list of unwanted capabilities
+ // then the capability will also be removed from the list of unwanted capabilities.
+ // TODO: Consider adding unwanted capabilities to the public API and mention this
+ // in the documentation.
checkValidCapability(capability);
mNetworkCapabilities |= 1 << capability;
mUnwantedNetworkCapabilities &= ~(1 << capability); // remove from unwanted capability list
@@ -439,16 +433,13 @@
/**
* Removes (if found) the given capability from this {@code NetworkCapability} instance.
- * <p>
- * Note that this method removes capabilities that were added via {@link #addCapability(int)},
- * {@link #addUnwantedCapability(int)} or {@link #setCapabilities(int[], int[])} .
*
* @param capability the capability to be removed.
* @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
*/
- @UnsupportedAppUsage
public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) {
+ // Note that this method removes capabilities that were added via addCapability(int),
+ // addUnwantedCapability(int) or setCapabilities(int[], int[]).
checkValidCapability(capability);
final long mask = ~(1 << capability);
mNetworkCapabilities &= mask;
@@ -460,7 +451,6 @@
* Sets (or clears) the given capability on this {@link NetworkCapabilities}
* instance.
*
- * @hide
*/
public @NonNull NetworkCapabilities setCapability(@NetCapability int capability,
boolean value) {
@@ -722,9 +712,7 @@
*
* @param transportType the transport type to be added.
* @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
*/
- @UnsupportedAppUsage
public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) {
checkValidTransportType(transportType);
mTransportTypes |= 1 << transportType;
@@ -863,7 +851,6 @@
* fast backhauls and slow backhauls.
*
* @param upKbps the estimated first hop upstream (device to network) bandwidth.
- * @hide
*/
public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) {
mLinkUpBandwidthKbps = upKbps;
@@ -893,7 +880,6 @@
* fast backhauls and slow backhauls.
*
* @param downKbps the estimated first hop downstream (network to device) bandwidth.
- * @hide
*/
public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) {
mLinkDownBandwidthKbps = downKbps;
@@ -952,9 +938,9 @@
* @param networkSpecifier A concrete, parcelable framework class that extends
* NetworkSpecifier.
* @return This NetworkCapabilities instance, to facilitate chaining.
- * @hide
*/
- public @NonNull NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) {
+ public @NonNull NetworkCapabilities setNetworkSpecifier(
+ @NonNull NetworkSpecifier networkSpecifier) {
if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) {
throw new IllegalStateException("Must have a single transport specified to use " +
"setNetworkSpecifier");
@@ -973,7 +959,8 @@
* @return This NetworkCapabilities instance, to facilitate chaining.
* @hide
*/
- public @NonNull NetworkCapabilities setTransportInfo(TransportInfo transportInfo) {
+ @SystemApi
+ public @NonNull NetworkCapabilities setTransportInfo(@NonNull TransportInfo transportInfo) {
mTransportInfo = transportInfo;
return this;
}
@@ -983,9 +970,7 @@
*
* @return The optional {@link NetworkSpecifier} specifying the bearer specific network
* specifier or {@code null}. See {@link #setNetworkSpecifier}.
- * @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public @Nullable NetworkSpecifier getNetworkSpecifier() {
return mNetworkSpecifier;
}
@@ -1054,9 +1039,7 @@
* effect when requesting a callback.
*
* @param signalStrength the bearer-specific signal strength.
- * @hide
*/
- @UnsupportedAppUsage
public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) {
mSignalStrength = signalStrength;
return this;
@@ -1282,6 +1265,7 @@
* Sets the SSID of this network.
* @hide
*/
+ @SystemApi
public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) {
mSSID = ssid;
return this;
@@ -1602,7 +1586,7 @@
}
/** @hide */
- public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
for (int transport : getTransportTypes()) {
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 4270740..2992127 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -17,6 +17,7 @@
package android.net;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
@@ -461,6 +462,14 @@
return networkCapabilities.hasTransport(transportType);
}
+ /**
+ * @see Builder#setNetworkSpecifier(NetworkSpecifier)
+ */
+ @Nullable
+ public NetworkSpecifier getNetworkSpecifier() {
+ return networkCapabilities.getNetworkSpecifier();
+ }
+
public String toString() {
return "NetworkRequest [ " + type + " id=" + requestId +
(legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
@@ -485,13 +494,13 @@
}
/** @hide */
- public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
proto.write(NetworkRequestProto.REQUEST_ID, requestId);
proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
- networkCapabilities.writeToProto(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
+ networkCapabilities.dumpDebug(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
proto.end(token);
}
diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java
index ec73866..fb224fb 100644
--- a/core/java/android/net/SocketKeepalive.java
+++ b/core/java/android/net/SocketKeepalive.java
@@ -147,17 +147,6 @@
}
}
- /**
- * This packet is invalid.
- * See the error code for details.
- * @hide
- */
- public static class InvalidPacketException extends ErrorCodeException {
- public InvalidPacketException(final int error) {
- super(error);
- }
- }
-
@NonNull final IConnectivityManager mService;
@NonNull final Network mNetwork;
@NonNull final ParcelFileDescriptor mPfd;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 50246f5..bd8a361 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -47,8 +47,6 @@
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
-import static com.android.internal.util.Preconditions.checkNotNull;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.BroadcastOptions;
@@ -77,7 +75,6 @@
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
import android.net.ISocketKeepaliveCallback;
-import android.net.ITetheringEventCallback;
import android.net.InetAddresses;
import android.net.IpMemoryStore;
import android.net.IpPrefix;
@@ -108,6 +105,7 @@
import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.net.SocketKeepalive;
+import android.net.TetheringManager;
import android.net.UidRange;
import android.net.Uri;
import android.net.VpnService;
@@ -187,9 +185,7 @@
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.server.connectivity.PermissionMonitor;
import com.android.server.connectivity.ProxyTracker;
-import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
-import com.android.server.connectivity.tethering.TetheringDependencies;
import com.android.server.net.BaseNetdEventCallback;
import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker;
@@ -233,7 +229,6 @@
private static final String DIAG_ARG = "--diag";
public static final String SHORT_ARG = "--short";
- private static final String TETHERING_ARG = "tethering";
private static final String NETWORK_ARG = "networks";
private static final String REQUEST_ARG = "requests";
@@ -280,8 +275,6 @@
private MockableSystemProperties mSystemProperties;
- private Tethering mTethering;
-
@VisibleForTesting
protected final PermissionMonitor mPermissionMonitor;
@@ -869,18 +862,6 @@
}
/**
- * @see Tethering
- */
- public Tethering makeTethering(@NonNull Context context,
- @NonNull INetworkManagementService nms,
- @NonNull INetworkStatsService statsService,
- @NonNull INetworkPolicyManager policyManager,
- @NonNull TetheringDependencies tetheringDeps) {
- return new Tethering(context, nms, statsService, policyManager,
- IoThread.get().getLooper(), getSystemProperties(), tetheringDeps);
- }
-
- /**
* @see ProxyTracker
*/
public ProxyTracker makeProxyTracker(@NonNull Context context,
@@ -921,7 +902,7 @@
* @see IpConnectivityMetrics.Logger
*/
public IpConnectivityMetrics.Logger getMetricsLogger() {
- return checkNotNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
+ return Objects.requireNonNull(LocalServices.getService(IpConnectivityMetrics.Logger.class),
"no IpConnectivityMetrics service");
}
@@ -932,6 +913,10 @@
return IIpConnectivityMetrics.Stub.asInterface(
ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
}
+
+ public IBatteryStats getBatteryStatsService() {
+ return BatteryStatsService.getService();
+ }
}
public ConnectivityService(Context context, INetworkManagementService netManager,
@@ -946,7 +931,7 @@
IDnsResolver dnsresolver, IpConnectivityLog logger, INetd netd, Dependencies deps) {
if (DBG) log("ConnectivityService starting up");
- mDeps = checkNotNull(deps, "missing Dependencies");
+ mDeps = Objects.requireNonNull(deps, "missing Dependencies");
mSystemProperties = mDeps.getSystemProperties();
mNetIdManager = mDeps.makeNetIdManager();
@@ -975,14 +960,14 @@
mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
- mContext = checkNotNull(context, "missing Context");
- mNMS = checkNotNull(netManager, "missing INetworkManagementService");
- mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
- mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
- mPolicyManagerInternal = checkNotNull(
+ mContext = Objects.requireNonNull(context, "missing Context");
+ mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
+ mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
+ mPolicyManager = Objects.requireNonNull(policyManager, "missing INetworkPolicyManager");
+ mPolicyManagerInternal = Objects.requireNonNull(
LocalServices.getService(NetworkPolicyManagerInternal.class),
"missing NetworkPolicyManagerInternal");
- mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
+ mDnsResolver = Objects.requireNonNull(dnsresolver, "missing IDnsResolver");
mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler);
mNetd = netd;
@@ -1075,9 +1060,6 @@
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mTethering = deps.makeTethering(mContext, mNMS, mStatsService, mPolicyManager,
- makeTetheringDependencies());
-
mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
// Set up the listener for user state for creating user VPNs.
@@ -1111,7 +1093,6 @@
mHandler);
try {
- mNMS.registerObserver(mTethering);
mNMS.registerObserver(mDataActivityObserver);
} catch (RemoteException e) {
loge("Error registering observer :" + e);
@@ -1145,19 +1126,6 @@
registerPrivateDnsSettingsCallbacks();
}
- private TetheringDependencies makeTetheringDependencies() {
- return new TetheringDependencies() {
- @Override
- public boolean isTetheringSupported() {
- return ConnectivityService.this.isTetheringSupported();
- }
- @Override
- public NetworkRequest getDefaultNetworkRequest() {
- return mDefaultRequest;
- }
- };
- }
-
private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
final NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addCapability(NET_CAPABILITY_INTERNET);
@@ -1413,7 +1381,7 @@
@Override
public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
- enforceConnectivityInternalPermission();
+ NetworkStack.checkNetworkStackPermission(mContext);
return getActiveNetworkForUidInternal(uid, ignoreBlocked);
}
@@ -1455,7 +1423,7 @@
@Override
public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
- enforceConnectivityInternalPermission();
+ NetworkStack.checkNetworkStackPermission(mContext);
final NetworkState state = getUnfilteredActiveNetworkState(uid);
filterNetworkStateForUid(state, uid, ignoreBlocked);
return state.networkInfo;
@@ -1674,8 +1642,8 @@
@Override
public NetworkState[] getAllNetworkState() {
- // Require internal since we're handing out IMSI details
- enforceConnectivityInternalPermission();
+ // This contains IMSI details, so make sure the caller is privileged.
+ NetworkStack.checkNetworkStackPermission(mContext);
final ArrayList<NetworkState> result = Lists.newArrayList();
for (Network network : getAllNetworks()) {
@@ -1753,7 +1721,7 @@
}
enforceChangePermission();
if (mProtectedNetworks.contains(networkType)) {
- enforceConnectivityInternalPermission();
+ enforceConnectivityRestrictedNetworksPermission();
}
InetAddress addr;
@@ -1905,12 +1873,6 @@
}
mHandler.sendMessage(mHandler.obtainMessage(
EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
-
- // TODO: relocate this specific callback in Tethering.
- if (restrictBackground) {
- log("onRestrictBackgroundChanged(true): disabling tethering");
- mTethering.untetherAll();
- }
}
};
@@ -2021,6 +1983,12 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
+ private void enforceNetworkFactoryPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.NETWORK_FACTORY,
+ "ConnectivityService");
+ }
+
private boolean checkSettingsPermission() {
return checkAnyPermissionOf(
android.Manifest.permission.NETWORK_SETTINGS,
@@ -2034,24 +2002,19 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, pid, uid);
}
- private void enforceTetherAccessPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NETWORK_STATE,
- "ConnectivityService");
- }
-
- private void enforceConnectivityInternalPermission() {
- enforceAnyPermissionOf(
- android.Manifest.permission.CONNECTIVITY_INTERNAL,
- NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
- }
-
private void enforceControlAlwaysOnVpnPermission() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CONTROL_ALWAYS_ON_VPN,
"ConnectivityService");
}
+ private void enforceNetworkStackOrSettingsPermission() {
+ enforceAnyPermissionOf(
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_STACK,
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+ }
+
private void enforceNetworkStackSettingsOrSetup() {
enforceAnyPermissionOf(
android.Manifest.permission.NETWORK_SETTINGS,
@@ -2088,7 +2051,11 @@
"ConnectivityService");
return;
} catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ }
- enforceConnectivityInternalPermission();
+ // TODO: Remove this fallback check after all apps have declared
+ // CONNECTIVITY_USE_RESTRICTED_NETWORKS.
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CONNECTIVITY_INTERNAL,
+ "ConnectivityService");
}
private void enforceKeepalivePermission() {
@@ -2097,7 +2064,7 @@
// Public because it's used by mLockdownTracker.
public void sendConnectedBroadcast(NetworkInfo info) {
- enforceConnectivityInternalPermission();
+ NetworkStack.checkNetworkStackPermission(mContext);
sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
}
@@ -2173,7 +2140,7 @@
opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
options = opts.toBundle();
}
- final IBatteryStats bs = BatteryStatsService.getService();
+ final IBatteryStats bs = mDeps.getBatteryStatsService();
try {
bs.noteConnectivityChanged(intent.getIntExtra(
ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE),
@@ -2202,7 +2169,6 @@
mPermissionMonitor.startMonitoring();
mProxyTracker.loadGlobalProxy();
registerNetdEventCallback();
- mTethering.systemReady();
synchronized (this) {
mSystemReady = true;
@@ -2414,9 +2380,6 @@
if (ArrayUtils.contains(args, DIAG_ARG)) {
dumpNetworkDiagnostics(pw);
return;
- } else if (ArrayUtils.contains(args, TETHERING_ARG)) {
- mTethering.dump(fd, pw, args);
- return;
} else if (ArrayUtils.contains(args, NETWORK_ARG)) {
dumpNetworks(pw);
return;
@@ -2478,9 +2441,6 @@
mLegacyTypeTracker.dump(pw);
pw.println();
- mTethering.dump(fd, pw, args);
-
- pw.println();
mKeepaliveTracker.dump(pw);
pw.println();
@@ -3615,7 +3575,7 @@
@Override
public void startCaptivePortalApp(Network network) {
- enforceConnectivityInternalPermission();
+ enforceNetworkStackOrSettingsPermission();
mHandler.post(() -> {
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai == null) return;
@@ -4008,181 +3968,55 @@
}
}
- // javadoc from interface
@Override
- public int tether(String iface, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- if (isTetheringSupported()) {
- return mTethering.tether(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // javadoc from interface
- @Override
- public int untether(String iface, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
-
- if (isTetheringSupported()) {
- return mTethering.untether(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // javadoc from interface
- @Override
+ @Deprecated
public int getLastTetherError(String iface) {
- enforceTetherAccessPermission();
-
- if (isTetheringSupported()) {
- return mTethering.getLastTetherError(iface);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // TODO - proper iface API for selection by property, inspection, etc
- @Override
- public String[] getTetherableUsbRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTethering.getTetherableUsbRegexs();
- } else {
- return new String[0];
- }
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getLastTetherError(iface);
}
@Override
- public String[] getTetherableWifiRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTethering.getTetherableWifiRegexs();
- } else {
- return new String[0];
- }
- }
-
- @Override
- public String[] getTetherableBluetoothRegexs() {
- enforceTetherAccessPermission();
- if (isTetheringSupported()) {
- return mTethering.getTetherableBluetoothRegexs();
- } else {
- return new String[0];
- }
- }
-
- @Override
- public int setUsbTethering(boolean enable, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- if (isTetheringSupported()) {
- return mTethering.setUsbTethering(enable);
- } else {
- return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
- }
- }
-
- // TODO - move iface listing, queries, etc to new module
- // javadoc from interface
- @Override
+ @Deprecated
public String[] getTetherableIfaces() {
- enforceTetherAccessPermission();
- return mTethering.getTetherableIfaces();
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getTetherableIfaces();
}
@Override
+ @Deprecated
public String[] getTetheredIfaces() {
- enforceTetherAccessPermission();
- return mTethering.getTetheredIfaces();
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getTetheredIfaces();
}
+
@Override
+ @Deprecated
public String[] getTetheringErroredIfaces() {
- enforceTetherAccessPermission();
- return mTethering.getErroredIfaces();
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+
+ return tm.getTetheringErroredIfaces();
}
@Override
- public String[] getTetheredDhcpRanges() {
- enforceConnectivityInternalPermission();
- return mTethering.getTetheredDhcpRanges();
+ @Deprecated
+ public String[] getTetherableUsbRegexs() {
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+
+ return tm.getTetherableUsbRegexs();
}
@Override
- public boolean isTetheringSupported(String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- return isTetheringSupported();
- }
-
- // if ro.tether.denied = true we default to no tethering
- // gservices could set the secure setting to 1 though to enable it on a build where it
- // had previously been turned off.
- private boolean isTetheringSupported() {
- int defaultVal = encodeBool(!mSystemProperties.get("ro.tether.denied").equals("true"));
- boolean tetherSupported = toBool(Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.TETHER_SUPPORTED, defaultVal));
- boolean tetherEnabledInSettings = tetherSupported
- && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
-
- // Elevate to system UID to avoid caller requiring MANAGE_USERS permission.
- boolean adminUser = false;
- final long token = Binder.clearCallingIdentity();
- try {
- adminUser = mUserManager.isAdminUser();
- } finally {
- Binder.restoreCallingIdentity(token);
- }
-
- return tetherEnabledInSettings && adminUser && mTethering.hasTetherableConfiguration();
- }
-
- @Override
- public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
- String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- if (!isTetheringSupported()) {
- receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
- return;
- }
- mTethering.startTethering(type, receiver, showProvisioningUi);
- }
-
- @Override
- public void stopTethering(int type, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTethering.stopTethering(type);
- }
-
- /**
- * Get the latest value of the tethering entitlement check.
- *
- * Note: Allow privileged apps who have TETHER_PRIVILEGED permission to access. If it turns
- * out some such apps are observed to abuse this API, change to per-UID limits on this API
- * if it's really needed.
- */
- @Override
- public void getLatestTetheringEntitlementResult(int type, ResultReceiver receiver,
- boolean showEntitlementUi, String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTethering.getLatestTetheringEntitlementResult(type, receiver, showEntitlementUi);
- }
-
- /** Register tethering event callback. */
- @Override
- public void registerTetheringEventCallback(ITetheringEventCallback callback,
- String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTethering.registerTetheringEventCallback(callback);
- }
-
- /** Unregister tethering event callback. */
- @Override
- public void unregisterTetheringEventCallback(ITetheringEventCallback callback,
- String callerPkg) {
- ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
- mTethering.unregisterTetheringEventCallback(callback);
+ @Deprecated
+ public String[] getTetherableWifiRegexs() {
+ final TetheringManager tm = (TetheringManager) mContext.getSystemService(
+ Context.TETHERING_SERVICE);
+ return tm.getTetherableWifiRegexs();
}
// Called when we lose the default network and have no replacement yet.
@@ -4328,7 +4162,7 @@
@Override
public void setGlobalProxy(final ProxyInfo proxyProperties) {
- enforceConnectivityInternalPermission();
+ NetworkStack.checkNetworkStackPermission(mContext);
mProxyTracker.setGlobalProxy(proxyProperties);
}
@@ -4867,7 +4701,7 @@
@Override
public String getMobileProvisioningUrl() {
- enforceConnectivityInternalPermission();
+ enforceSettingsPermission();
String url = getProvisioningUrlBaseFromFile();
if (TextUtils.isEmpty(url)) {
url = mContext.getResources().getString(R.string.mobile_provisioning_url);
@@ -4893,7 +4727,7 @@
@Override
public void setProvisioningNotificationVisible(boolean visible, int networkType,
String action) {
- enforceConnectivityInternalPermission();
+ enforceSettingsPermission();
if (!ConnectivityManager.isNetworkTypeValid(networkType)) {
return;
}
@@ -5368,7 +5202,7 @@
@Override
public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
PendingIntent operation) {
- checkNotNull(operation, "PendingIntent cannot be null.");
+ Objects.requireNonNull(operation, "PendingIntent cannot be null.");
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceMeteredApnPolicy(networkCapabilities);
@@ -5395,7 +5229,7 @@
@Override
public void releasePendingNetworkRequest(PendingIntent operation) {
- checkNotNull(operation, "PendingIntent cannot be null.");
+ Objects.requireNonNull(operation, "PendingIntent cannot be null.");
mHandler.sendMessage(mHandler.obtainMessage(EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT,
getCallingUid(), 0, operation));
}
@@ -5453,7 +5287,7 @@
@Override
public void pendingListenForNetwork(NetworkCapabilities networkCapabilities,
PendingIntent operation) {
- checkNotNull(operation, "PendingIntent cannot be null.");
+ Objects.requireNonNull(operation, "PendingIntent cannot be null.");
if (!hasWifiNetworkListenPermission(networkCapabilities)) {
enforceAccessPermission();
}
@@ -5481,7 +5315,7 @@
@Override
public int registerNetworkFactory(Messenger messenger, String name) {
- enforceConnectivityInternalPermission();
+ enforceNetworkFactoryPermission();
NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(),
NetworkFactory.SerialNumber.nextSerialNumber());
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
@@ -5496,7 +5330,7 @@
@Override
public void unregisterNetworkFactory(Messenger messenger) {
- enforceConnectivityInternalPermission();
+ enforceNetworkFactoryPermission();
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
}
@@ -5586,7 +5420,7 @@
* @param linkProperties the initial link properties of this network. They can be updated
* later : see {@link #updateLinkProperties}.
* @param networkCapabilities the initial capabilites of this network. They can be updated
- * later : see {@link #updateNetworkCapabilities}.
+ * later : see {@link #updateCapabilities}.
* @param currentScore the initial score of the network. See
* {@link NetworkAgentInfo#getCurrentScore}.
* @param networkMisc metadata about the network. This is never updated.
@@ -5595,7 +5429,7 @@
public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkMisc networkMisc, int factorySerialNumber) {
- enforceConnectivityInternalPermission();
+ enforceNetworkFactoryPermission();
LinkProperties lp = new LinkProperties(linkProperties);
lp.ensureDirectlyConnectedRoutes();
@@ -5609,7 +5443,7 @@
ns, mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd,
mDnsResolver, mNMS, factorySerialNumber);
// Make sure the network capabilities reflect what the agent info says.
- nai.setNetworkCapabilities(mixInCapabilities(nai, nc));
+ nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
final String extraInfo = networkInfo.getExtraInfo();
final String name = TextUtils.isEmpty(extraInfo)
? nai.networkCapabilities.getSSID() : extraInfo;
@@ -5656,7 +5490,8 @@
// are accurate.
networkAgent.clatd.fixupLinkProperties(oldLp, newLp);
- updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities);
+ updateInterfaces(newLp, oldLp, netId, networkAgent.networkCapabilities,
+ networkAgent.networkInfo.getType());
// update filtering rules, need to happen after the interface update so netd knows about the
// new interface (the interface name -> index map becomes initialized)
@@ -5735,21 +5570,26 @@
}
- private void updateInterfaces(LinkProperties newLp, LinkProperties oldLp, int netId,
- NetworkCapabilities caps) {
- CompareResult<String> interfaceDiff = new CompareResult<>(
+ private void updateInterfaces(final @Nullable LinkProperties newLp,
+ final @Nullable LinkProperties oldLp, final int netId,
+ final @Nullable NetworkCapabilities caps, final int legacyType) {
+ final CompareResult<String> interfaceDiff = new CompareResult<>(
oldLp != null ? oldLp.getAllInterfaceNames() : null,
newLp != null ? newLp.getAllInterfaceNames() : null);
- for (String iface : interfaceDiff.added) {
- try {
- if (DBG) log("Adding iface " + iface + " to network " + netId);
- mNMS.addInterfaceToNetwork(iface, netId);
- wakeupModifyInterface(iface, caps, true);
- } catch (Exception e) {
- loge("Exception adding interface: " + e);
+ if (!interfaceDiff.added.isEmpty()) {
+ final IBatteryStats bs = mDeps.getBatteryStatsService();
+ for (final String iface : interfaceDiff.added) {
+ try {
+ if (DBG) log("Adding iface " + iface + " to network " + netId);
+ mNMS.addInterfaceToNetwork(iface, netId);
+ wakeupModifyInterface(iface, caps, true);
+ bs.noteNetworkInterfaceType(iface, legacyType);
+ } catch (Exception e) {
+ loge("Exception adding interface: " + e);
+ }
}
}
- for (String iface : interfaceDiff.removed) {
+ for (final String iface : interfaceDiff.removed) {
try {
if (DBG) log("Removing iface " + iface + " from network " + netId);
wakeupModifyInterface(iface, caps, false);
@@ -5957,11 +5797,7 @@
}
}
- final NetworkCapabilities prevNc;
- synchronized (nai) {
- prevNc = nai.networkCapabilities;
- nai.setNetworkCapabilities(newNc);
- }
+ final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
updateUids(nai, prevNc, newNc);
@@ -5970,7 +5806,7 @@
// the change we're processing can't affect any requests, it can only affect the listens
// on this network. We might have been called by rematchNetworkAndRequests when a
// network changed foreground state.
- processListenRequests(nai, true);
+ processListenRequests(nai);
} else {
// If the requestable capabilities have changed or the score changed, we can't have been
// called by rematchNetworkAndRequests, so it's safe to start a rematch.
@@ -6278,8 +6114,14 @@
updateAllVpnsCapabilities();
}
- private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) {
+ private void processListenRequests(@NonNull final NetworkAgentInfo nai) {
// For consistency with previous behaviour, send onLost callbacks before onAvailable.
+ processNewlyLostListenRequests(nai);
+ notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
+ processNewlySatisfiedListenRequests(nai);
+ }
+
+ private void processNewlyLostListenRequests(@NonNull final NetworkAgentInfo nai) {
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
NetworkRequest nr = nri.request;
if (!nr.isListen()) continue;
@@ -6288,11 +6130,9 @@
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_LOST, 0);
}
}
+ }
- if (capabilitiesChanged) {
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
- }
-
+ private void processNewlySatisfiedListenRequests(@NonNull final NetworkAgentInfo nai) {
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
NetworkRequest nr = nri.request;
if (!nr.isListen()) continue;
@@ -6471,91 +6311,36 @@
newNetwork.name(), score, newNetwork.getCurrentScore()));
}
- // Second pass: process all listens.
- if (wasBackgroundNetwork != newNetwork.isBackgroundNetwork()) {
- // If the network went from background to foreground or vice versa, we need to update
- // its foreground state. It is safe to do this after rematching the requests because
- // NET_CAPABILITY_FOREGROUND does not affect requests, as is not a requestable
- // capability and does not affect the network's score (see the Slog.wtf call above).
- updateCapabilities(score, newNetwork, newNetwork.networkCapabilities);
- } else {
- processListenRequests(newNetwork, false);
- }
-
- // do this after the default net is switched, but
+ // Notify requested networks are available after the default net is switched, but
// before LegacyTypeTracker sends legacy broadcasts
for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri);
- // Linger any networks that are no longer needed. This should be done after sending the
- // available callback for newNetwork.
- for (NetworkAgentInfo nai : removedRequests) {
- updateLingerState(nai, now);
- }
- // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it
- // does not need to be done in any particular order.
- updateLingerState(newNetwork, now);
+ // Finally, process listen requests and update capabilities if the background state has
+ // changed for this network. For consistency with previous behavior, send onLost callbacks
+ // before onAvailable.
+ processNewlyLostListenRequests(newNetwork);
- if (isNewDefault) {
- // Maintain the illusion: since the legacy API only
- // understands one network at a time, we must pretend
- // that the current default network disconnected before
- // the new one connected.
- if (oldDefaultNetwork != null) {
- mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
- oldDefaultNetwork, true);
- }
- mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0;
- mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
- notifyLockdownVpn(newNetwork);
- }
+ // Maybe the network changed background states. Update its capabilities.
+ final boolean backgroundChanged = wasBackgroundNetwork != newNetwork.isBackgroundNetwork();
+ if (backgroundChanged) {
+ final NetworkCapabilities newNc = mixInCapabilities(newNetwork,
+ newNetwork.networkCapabilities);
- if (reassignedRequests.containsValue(newNetwork) || newNetwork.isVPN()) {
- // Notify battery stats service about this network, both the normal
- // interface and any stacked links.
- // TODO: Avoid redoing this; this must only be done once when a network comes online.
- try {
- final IBatteryStats bs = BatteryStatsService.getService();
- final int type = newNetwork.networkInfo.getType();
-
- final String baseIface = newNetwork.linkProperties.getInterfaceName();
- bs.noteNetworkInterfaceType(baseIface, type);
- for (LinkProperties stacked : newNetwork.linkProperties.getStackedLinks()) {
- final String stackedIface = stacked.getInterfaceName();
- bs.noteNetworkInterfaceType(stackedIface, type);
- }
- } catch (RemoteException ignored) {
- }
-
- // This has to happen after the notifyNetworkCallbacks as that tickles each
- // ConnectivityManager instance so that legacy requests correctly bind dns
- // requests to this network. The legacy users are listening for this broadcast
- // and will generally do a dns request so they can ensureRouteToHost and if
- // they do that before the callbacks happen they'll use the default network.
- //
- // TODO: Is there still a race here? We send the broadcast
- // after sending the callback, but if the app can receive the
- // broadcast before the callback, it might still break.
- //
- // This *does* introduce a race where if the user uses the new api
- // (notification callbacks) and then uses the old api (getNetworkInfo(type))
- // they may get old info. Reverse this after the old startUsing api is removed.
- // This is on top of the multiple intent sequencing referenced in the todo above.
- for (int i = 0; i < newNetwork.numNetworkRequests(); i++) {
- NetworkRequest nr = newNetwork.requestAt(i);
- if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
- // legacy type tracker filters out repeat adds
- mLegacyTypeTracker.add(nr.legacyType, newNetwork);
+ final int oldPermission = getNetworkPermission(newNetwork.networkCapabilities);
+ final int newPermission = getNetworkPermission(newNc);
+ if (oldPermission != newPermission) {
+ try {
+ mNMS.setNetworkPermission(newNetwork.network.netId, newPermission);
+ } catch (RemoteException e) {
+ loge("Exception in setNetworkPermission: " + e);
}
}
- // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
- // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
- // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
- // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
- if (newNetwork.isVPN()) {
- mLegacyTypeTracker.add(TYPE_VPN, newNetwork);
- }
+ newNetwork.getAndSetNetworkCapabilities(newNc);
+ notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_CAP_CHANGED);
}
+
+ processNewlySatisfiedListenRequests(newNetwork);
}
/**
@@ -6569,15 +6354,32 @@
// requests. Once the code has switched to a request-major iteration style, this can
// be optimized to only do the processing needed.
final long now = SystemClock.elapsedRealtime();
+ final NetworkAgentInfo oldDefaultNetwork = getDefaultNetwork();
+
final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray(
new NetworkAgentInfo[mNetworkAgentInfos.size()]);
// Rematch higher scoring networks first to prevent requests first matching a lower
// scoring network and then a higher scoring network, which could produce multiple
- // callbacks and inadvertently unlinger networks.
+ // callbacks.
Arrays.sort(nais);
- for (NetworkAgentInfo nai : nais) {
+ for (final NetworkAgentInfo nai : nais) {
rematchNetworkAndRequests(nai, now);
}
+
+ final NetworkAgentInfo newDefaultNetwork = getDefaultNetwork();
+
+ for (final NetworkAgentInfo nai : nais) {
+ // Rematching may have altered the linger state of some networks, so update all linger
+ // timers. updateLingerState reads the state from the network agent and does nothing
+ // if the state has not changed : the source of truth is controlled with
+ // NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which have been
+ // called while rematching the individual networks above.
+ updateLingerState(nai, now);
+ }
+
+ updateLegacyTypeTrackerAndVpnLockdownForRematch(oldDefaultNetwork, newDefaultNetwork, nais);
+
+ // Tear down all unneeded networks.
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
if (unneeded(nai, UnneededFor.TEARDOWN)) {
if (nai.getLingerExpiry() > 0) {
@@ -6597,6 +6399,70 @@
}
}
+ private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
+ @Nullable final NetworkAgentInfo oldDefaultNetwork,
+ @Nullable final NetworkAgentInfo newDefaultNetwork,
+ @NonNull final NetworkAgentInfo[] nais) {
+ if (oldDefaultNetwork != newDefaultNetwork) {
+ // Maintain the illusion : since the legacy API only understands one network at a time,
+ // if the default network changed, apps should see a disconnected broadcast for the
+ // old default network before they see a connected broadcast for the new one.
+ if (oldDefaultNetwork != null) {
+ mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
+ oldDefaultNetwork, true);
+ }
+ if (newDefaultNetwork != null) {
+ // The new default network can be newly null if and only if the old default
+ // network doesn't satisfy the default request any more because it lost a
+ // capability.
+ mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
+ mLegacyTypeTracker.add(newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
+ // If the legacy VPN is connected, notifyLockdownVpn may end up sending a broadcast
+ // to reflect the NetworkInfo of this new network. This broadcast has to be sent
+ // after the disconnect broadcasts above, but before the broadcasts sent by the
+ // legacy type tracker below.
+ // TODO : refactor this, it's too complex
+ notifyLockdownVpn(newDefaultNetwork);
+ }
+ }
+
+ // Now that all the callbacks have been sent, send the legacy network broadcasts
+ // as needed. This is necessary so that legacy requests correctly bind dns
+ // requests to this network. The legacy users are listening for this broadcast
+ // and will generally do a dns request so they can ensureRouteToHost and if
+ // they do that before the callbacks happen they'll use the default network.
+ //
+ // TODO: Is there still a race here? The legacy broadcast will be sent after sending
+ // callbacks, but if apps can receive the broadcast before the callback, they still might
+ // have an inconsistent view of networking.
+ //
+ // This *does* introduce a race where if the user uses the new api
+ // (notification callbacks) and then uses the old api (getNetworkInfo(type))
+ // they may get old info. Reverse this after the old startUsing api is removed.
+ // This is on top of the multiple intent sequencing referenced in the todo above.
+ for (NetworkAgentInfo nai : nais) {
+ addNetworkToLegacyTypeTracker(nai);
+ }
+ }
+
+ private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) {
+ for (int i = 0; i < nai.numNetworkRequests(); i++) {
+ NetworkRequest nr = nai.requestAt(i);
+ if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
+ // legacy type tracker filters out repeat adds
+ mLegacyTypeTracker.add(nr.legacyType, nai);
+ }
+ }
+
+ // A VPN generally won't get added to the legacy tracker in the "for (nri)" loop above,
+ // because usually there are no NetworkRequests it satisfies (e.g., mDefaultRequest
+ // wants the NOT_VPN capability, so it will never be satisfied by a VPN). So, add the
+ // newNetwork to the tracker explicitly (it's a no-op if it has already been added).
+ if (nai.isVPN()) {
+ mLegacyTypeTracker.add(TYPE_VPN, nai);
+ }
+ }
+
private void updateInetCondition(NetworkAgentInfo nai) {
// Don't bother updating until we've graduated to validated at least once.
if (!nai.everValidated) return;
@@ -6659,9 +6525,8 @@
// NetworkCapabilities need to be set before sending the private DNS config to
// NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
- synchronized (networkAgent) {
- networkAgent.setNetworkCapabilities(networkAgent.networkCapabilities);
- }
+ networkAgent.getAndSetNetworkCapabilities(networkAgent.networkCapabilities);
+
handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
null);
@@ -6963,7 +6828,7 @@
@Override
public String getCaptivePortalServerUrl() {
- enforceConnectivityInternalPermission();
+ enforceNetworkStackOrSettingsPermission();
String settingUrl = mContext.getResources().getString(
R.string.config_networkCaptivePortalServerUrl);
@@ -7016,7 +6881,7 @@
@Override
public void factoryReset() {
- enforceConnectivityInternalPermission();
+ enforceSettingsPermission();
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
return;
@@ -7032,14 +6897,6 @@
// Turn airplane mode off
setAirplaneMode(false);
- if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
- // Untether
- String pkgName = mContext.getOpPackageName();
- for (String tether : getTetheredIfaces()) {
- untether(tether, pkgName);
- }
- }
-
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN)) {
// Remove always-on package
synchronized (mVpns) {
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index d19d2dd..c27b0da 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -16,8 +16,6 @@
package com.android.server;
-import static com.android.internal.util.Preconditions.checkNotNull;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -55,6 +53,7 @@
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
/** @hide */
@@ -82,9 +81,9 @@
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
- mContext = checkNotNull(context, "missing Context");
- mNMS = checkNotNull(netManager, "missing INetworkManagementService");
- mNetd = checkNotNull(NetdService.getInstance(), "could not get netd instance");
+ mContext = Objects.requireNonNull(context, "missing Context");
+ mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
+ mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
}
/**
@@ -96,7 +95,7 @@
private TestNetworkInterface createInterface(boolean isTun, LinkAddress[] linkAddrs) {
enforceTestNetworkPermissions(mContext);
- checkNotNull(linkAddrs, "missing linkAddrs");
+ Objects.requireNonNull(linkAddrs, "missing linkAddrs");
String ifacePrefix = isTun ? TEST_TUN_PREFIX : TEST_TAP_PREFIX;
String iface = ifacePrefix + sTestTunIndex.getAndIncrement();
@@ -233,8 +232,8 @@
int callingUid,
@NonNull IBinder binder)
throws RemoteException, SocketException {
- checkNotNull(looper, "missing Looper");
- checkNotNull(context, "missing Context");
+ Objects.requireNonNull(looper, "missing Looper");
+ Objects.requireNonNull(context, "missing Context");
// iface and binder validity checked by caller
// Build network info with special testing type
@@ -267,7 +266,7 @@
// Find the currently assigned addresses, and add them to LinkProperties
boolean allowIPv4 = false, allowIPv6 = false;
NetworkInterface netIntf = NetworkInterface.getByName(iface);
- checkNotNull(netIntf, "No such network interface found: " + netIntf);
+ Objects.requireNonNull(netIntf, "No such network interface found: " + netIntf);
for (InterfaceAddress intfAddr : netIntf.getInterfaceAddresses()) {
lp.addLinkAddress(
@@ -305,8 +304,8 @@
@NonNull IBinder binder) {
enforceTestNetworkPermissions(mContext);
- checkNotNull(iface, "missing Iface");
- checkNotNull(binder, "missing IBinder");
+ Objects.requireNonNull(iface, "missing Iface");
+ Objects.requireNonNull(binder, "missing IBinder");
if (!(iface.startsWith(INetd.IPSEC_INTERFACE_PREFIX)
|| iface.startsWith(TEST_TUN_PREFIX))) {
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index 2321afb..5250a77 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -337,7 +337,6 @@
.collect(Collectors.toList()))
: useTls ? paramsParcel.servers // Opportunistic
: new String[0]; // Off
- paramsParcel.tlsFingerprints = new String[0];
// Prepare to track the validation status of the DNS servers in the
// resolver config when private DNS is in opportunistic or strict mode.
if (useTls) {
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 9bae902..af8a366 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -39,11 +39,11 @@
import android.annotation.Nullable;
import android.content.Context;
import android.net.ISocketKeepaliveCallback;
+import android.net.InvalidPacketException;
import android.net.KeepalivePacketData;
import android.net.NattKeepalivePacketData;
import android.net.NetworkAgent;
import android.net.NetworkUtils;
-import android.net.SocketKeepalive.InvalidPacketException;
import android.net.SocketKeepalive.InvalidSocketException;
import android.net.TcpKeepalivePacketData;
import android.net.util.IpUtils;
@@ -657,7 +657,10 @@
final TcpKeepalivePacketData packet;
try {
packet = TcpKeepaliveController.getTcpKeepalivePacket(fd);
- } catch (InvalidPacketException | InvalidSocketException e) {
+ } catch (InvalidSocketException e) {
+ notifyErrorCallback(cb, e.error);
+ return;
+ } catch (InvalidPacketException e) {
notifyErrorCallback(cb, e.error);
return;
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 24a5b7f..5e085ca 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -291,13 +291,18 @@
*
* <p>If {@link NetworkMonitor#notifyNetworkCapabilitiesChanged(NetworkCapabilities)} fails,
* the exception is logged but not reported to callers.
+ *
+ * @return the old capabilities of this network.
*/
- public void setNetworkCapabilities(NetworkCapabilities nc) {
+ public synchronized NetworkCapabilities getAndSetNetworkCapabilities(
+ @NonNull final NetworkCapabilities nc) {
+ final NetworkCapabilities oldNc = networkCapabilities;
networkCapabilities = nc;
final NetworkMonitorManager nm = mNetworkMonitor;
if (nm != null) {
nm.notifyNetworkCapabilitiesChanged(nc);
}
+ return oldNc;
}
public ConnectivityService connService() {
@@ -580,7 +585,7 @@
// semantics of WakeupMessage guarantee that if cancel is called then the alarm will
// never call its callback (handleLingerComplete), even if it has already fired.
// WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage
- // has already been dispatched, rescheduling to some time in the future it won't stop it
+ // has already been dispatched, rescheduling to some time in the future won't stop it
// from calling its callback immediately.
if (mLingerMessage != null) {
mLingerMessage.cancel();
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index bc83780..2179518 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -31,7 +31,6 @@
import android.net.StringNetworkSpecifier;
import android.net.wifi.WifiInfo;
import android.os.UserHandle;
-import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -105,8 +104,7 @@
return -1;
}
- // TODO: Remove @TransportType or change it to @Transport.
- private static String getTransportName(@TransportType int transportType) {
+ private static String getTransportName(final int transportType) {
Resources r = Resources.getSystem();
String[] networkTypes = r.getStringArray(R.array.network_switch_type_name);
try {
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 56f4959..f0b7150 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -17,7 +17,6 @@
package com.android.server.connectivity;
import static android.Manifest.permission.CHANGE_NETWORK_STATE;
-import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.INTERNET;
import static android.Manifest.permission.NETWORK_STACK;
@@ -25,6 +24,7 @@
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
@@ -259,7 +259,8 @@
return true;
}
}
- return hasPermission(app, CONNECTIVITY_INTERNAL)
+
+ return hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK)
|| hasPermission(app, NETWORK_STACK)
|| hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
}
diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
index e570ef1..1129899 100644
--- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
+++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
@@ -30,8 +30,8 @@
import static android.system.OsConstants.TIOCOUTQ;
import android.annotation.NonNull;
+import android.net.InvalidPacketException;
import android.net.NetworkUtils;
-import android.net.SocketKeepalive.InvalidPacketException;
import android.net.SocketKeepalive.InvalidSocketException;
import android.net.TcpKeepalivePacketData;
import android.net.TcpKeepalivePacketDataParcelable;
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 10f27e2..b2f384a 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -45,7 +45,6 @@
name: "FrameworksNetTests",
defaults: ["FrameworksNetTests-jni-defaults"],
srcs: [
- ":tethering-tests-src",
"java/**/*.java",
"java/**/*.kt",
],
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index ae8285b..a7eef05 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -16,7 +16,9 @@
package android.net;
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -47,25 +49,22 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LinkPropertiesTest {
- private static final InetAddress ADDRV4 = InetAddresses.parseNumericAddress("75.208.6.1");
- private static final InetAddress ADDRV6 = InetAddresses.parseNumericAddress(
- "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
- private static final InetAddress DNS1 = InetAddresses.parseNumericAddress("75.208.7.1");
- private static final InetAddress DNS2 = InetAddresses.parseNumericAddress("69.78.7.1");
- private static final InetAddress DNS6 = InetAddresses.parseNumericAddress(
- "2001:4860:4860::8888");
- private static final InetAddress PRIVDNS1 = InetAddresses.parseNumericAddress("1.1.1.1");
- private static final InetAddress PRIVDNS2 = InetAddresses.parseNumericAddress("1.0.0.1");
- private static final InetAddress PRIVDNS6 = InetAddresses.parseNumericAddress(
- "2606:4700:4700::1111");
- private static final InetAddress PCSCFV4 = InetAddresses.parseNumericAddress("10.77.25.37");
- private static final InetAddress PCSCFV6 = InetAddresses.parseNumericAddress(
- "2001:0db8:85a3:0000:0000:8a2e:0370:1");
- private static final InetAddress GATEWAY1 = InetAddresses.parseNumericAddress("75.208.8.1");
- private static final InetAddress GATEWAY2 = InetAddresses.parseNumericAddress("69.78.8.1");
- private static final InetAddress GATEWAY61 = InetAddresses.parseNumericAddress(
- "fe80::6:0000:613");
- private static final InetAddress GATEWAY62 = InetAddresses.parseNumericAddress("fe80::6:2222");
+ private static final InetAddress ADDRV4 = address("75.208.6.1");
+ private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+ private static final InetAddress DNS1 = address("75.208.7.1");
+ private static final InetAddress DNS2 = address("69.78.7.1");
+ private static final InetAddress DNS6 = address("2001:4860:4860::8888");
+ private static final InetAddress PRIVDNS1 = address("1.1.1.1");
+ private static final InetAddress PRIVDNS2 = address("1.0.0.1");
+ private static final InetAddress PRIVDNS6 = address("2606:4700:4700::1111");
+ private static final InetAddress PCSCFV4 = address("10.77.25.37");
+ private static final InetAddress PCSCFV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:1");
+ private static final InetAddress GATEWAY1 = address("75.208.8.1");
+ private static final InetAddress GATEWAY2 = address("69.78.8.1");
+ private static final InetAddress GATEWAY61 = address("fe80::6:0000:613");
+ private static final InetAddress GATEWAY62 = address("fe80::6:22%lo");
+ private static final InetAddress TESTIPV4ADDR = address("192.168.47.42");
+ private static final InetAddress TESTIPV6ADDR = address("fe80::7:33%43");
private static final String NAME = "qmi0";
private static final String DOMAINS = "google.com";
private static final String PRIV_DNS_SERVER_NAME = "private.dns.com";
@@ -75,8 +74,7 @@
private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
- // TODO: replace all calls to NetworkUtils.numericToInetAddress with calls to this method.
- private InetAddress Address(String addrString) {
+ private static InetAddress address(String addrString) {
return InetAddresses.parseNumericAddress(addrString);
}
@@ -228,7 +226,7 @@
target.clear();
target.setInterfaceName(NAME);
// change link addresses
- target.addLinkAddress(new LinkAddress(Address("75.208.6.2"), 32));
+ target.addLinkAddress(new LinkAddress(address("75.208.6.2"), 32));
target.addLinkAddress(LINKADDRV6);
target.addDnsServer(DNS1);
target.addDnsServer(DNS2);
@@ -243,7 +241,7 @@
target.addLinkAddress(LINKADDRV4);
target.addLinkAddress(LINKADDRV6);
// change dnses
- target.addDnsServer(Address("75.208.7.2"));
+ target.addDnsServer(address("75.208.7.2"));
target.addDnsServer(DNS2);
target.addPcscfServer(PCSCFV6);
target.addRoute(new RouteInfo(GATEWAY1));
@@ -255,10 +253,10 @@
target.setInterfaceName(NAME);
target.addLinkAddress(LINKADDRV4);
target.addLinkAddress(LINKADDRV6);
- target.addDnsServer(Address("75.208.7.2"));
+ target.addDnsServer(address("75.208.7.2"));
target.addDnsServer(DNS2);
// change pcscf
- target.addPcscfServer(Address("2001::1"));
+ target.addPcscfServer(address("2001::1"));
target.addRoute(new RouteInfo(GATEWAY1));
target.addRoute(new RouteInfo(GATEWAY2));
target.setMtu(MTU);
@@ -271,9 +269,9 @@
target.addDnsServer(DNS1);
target.addDnsServer(DNS2);
// change gateway
- target.addRoute(new RouteInfo(Address("75.208.8.2")));
- target.addRoute(new RouteInfo(GATEWAY2));
+ target.addRoute(new RouteInfo(address("75.208.8.2")));
target.setMtu(MTU);
+ target.addRoute(new RouteInfo(GATEWAY2));
assertFalse(source.equals(target));
target.clear();
@@ -349,7 +347,7 @@
@Test
public void testRouteInterfaces() {
- LinkAddress prefix = new LinkAddress(Address("2001:db8::"), 32);
+ LinkAddress prefix = new LinkAddress(address("2001:db8::"), 32);
InetAddress address = ADDRV6;
// Add a route with no interface to a LinkProperties with no interface. No errors.
@@ -739,8 +737,7 @@
// Add an on-link route, making the on-link DNS server reachable,
// but there is still no IPv4 address.
- assertTrue(v4lp.addRoute(new RouteInfo(
- new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
+ assertTrue(v4lp.addRoute(new RouteInfo(new IpPrefix(address("75.208.0.0"), 16))));
assertFalse(v4lp.isReachable(DNS1));
assertFalse(v4lp.isReachable(DNS2));
@@ -756,9 +753,9 @@
assertTrue(v4lp.isReachable(DNS2));
final LinkProperties v6lp = new LinkProperties();
- final InetAddress kLinkLocalDns = Address("fe80::6:1");
- final InetAddress kLinkLocalDnsWithScope = Address("fe80::6:2%43");
- final InetAddress kOnLinkDns = Address("2001:db8:85a3::53");
+ final InetAddress kLinkLocalDns = address("fe80::6:1");
+ final InetAddress kLinkLocalDnsWithScope = address("fe80::6:2%43");
+ final InetAddress kOnLinkDns = address("2001:db8:85a3::53");
assertFalse(v6lp.isReachable(kLinkLocalDns));
assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
assertFalse(v6lp.isReachable(kOnLinkDns));
@@ -767,7 +764,7 @@
// Add a link-local route, making the link-local DNS servers reachable. Because
// we assume the presence of an IPv6 link-local address, link-local DNS servers
// are considered reachable, but only those with a non-zero scope identifier.
- assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(Address("fe80::"), 64))));
+ assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("fe80::"), 64))));
assertFalse(v6lp.isReachable(kLinkLocalDns));
assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
assertFalse(v6lp.isReachable(kOnLinkDns));
@@ -783,7 +780,7 @@
// Add a global route on link, but no global address yet. DNS servers reachable
// via a route that doesn't require a gateway: give them the benefit of the
// doubt and hope the link-local source address suffices for communication.
- assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(Address("2001:db8:85a3::"), 64))));
+ assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("2001:db8:85a3::"), 64))));
assertFalse(v6lp.isReachable(kLinkLocalDns));
assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
assertTrue(v6lp.isReachable(kOnLinkDns));
@@ -812,7 +809,7 @@
stacked.setInterfaceName("v4-test0");
v6lp.addStackedLink(stacked);
- InetAddress stackedAddress = Address("192.0.0.4");
+ InetAddress stackedAddress = address("192.0.0.4");
LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
assertFalse(v6lp.isReachable(stackedAddress));
stacked.addLinkAddress(stackedLinkAddress);
@@ -845,7 +842,7 @@
LinkProperties rmnet1 = new LinkProperties();
rmnet1.setInterfaceName("rmnet1");
rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
- RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null, Address("10.0.0.1"),
+ RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null, address("10.0.0.1"),
rmnet1.getInterfaceName());
RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
rmnet1.getInterfaceName());
@@ -864,7 +861,7 @@
rmnet2.setInterfaceName("rmnet2");
rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
- RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null, Address("2001:db8::1"),
+ RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null, address("2001:db8::1"),
rmnet2.getInterfaceName());
RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
rmnet2.getInterfaceName());
@@ -930,24 +927,54 @@
public void testLinkPropertiesParcelable() throws Exception {
LinkProperties source = new LinkProperties();
source.setInterfaceName(NAME);
- // set 2 link addresses
+
source.addLinkAddress(LINKADDRV4);
source.addLinkAddress(LINKADDRV6);
- // set 2 dnses
+
source.addDnsServer(DNS1);
source.addDnsServer(DNS2);
- // set 2 gateways
+ source.addDnsServer(GATEWAY62);
+
+ source.addPcscfServer(TESTIPV4ADDR);
+ source.addPcscfServer(TESTIPV6ADDR);
+
+ source.setUsePrivateDns(true);
+ source.setPrivateDnsServerName(PRIV_DNS_SERVER_NAME);
+
+ source.setDomains(DOMAINS);
+
source.addRoute(new RouteInfo(GATEWAY1));
source.addRoute(new RouteInfo(GATEWAY2));
- // set 2 validated private dnses
+
source.addValidatedPrivateDnsServer(DNS6);
source.addValidatedPrivateDnsServer(GATEWAY61);
+ source.addValidatedPrivateDnsServer(TESTIPV6ADDR);
+
+ source.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888));
source.setMtu(MTU);
+ source.setTcpBufferSizes(TCP_BUFFER_SIZES);
+
source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
- assertParcelingIsLossless(source);
+ source.setWakeOnLanSupported(true);
+
+ final LinkProperties stacked = new LinkProperties();
+ stacked.setInterfaceName("test-stacked");
+ source.addStackedLink(stacked);
+
+ assertParcelSane(source, 15 /* fieldCount */);
+ }
+
+ @Test
+ public void testLinkLocalDnsServerParceling() throws Exception {
+ final String strAddress = "fe80::1%lo";
+ final LinkProperties lp = new LinkProperties();
+ lp.addDnsServer(address(strAddress));
+ final LinkProperties unparceled = parcelingRoundTrip(lp);
+ // Inet6Address#equals does not test for the scope id
+ assertEquals(strAddress, unparceled.getDnsServers().get(0).getHostAddress());
}
@Test
diff --git a/tests/net/integration/AndroidManifest.xml b/tests/net/integration/AndroidManifest.xml
index 4dd3b5a..09c0e48 100644
--- a/tests/net/integration/AndroidManifest.xml
+++ b/tests/net/integration/AndroidManifest.xml
@@ -28,7 +28,9 @@
<!-- Reading network status -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+ <uses-permission android:name="android.permission.NETWORK_FACTORY" />
+ <uses-permission android:name="android.permission.NETWORK_STACK" />
+ <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<!-- Reading DeviceConfig flags -->
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 334b26d..c4801aa 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -48,7 +48,6 @@
import com.android.server.connectivity.IpConnectivityMetrics
import com.android.server.connectivity.MockableSystemProperties
import com.android.server.connectivity.ProxyTracker
-import com.android.server.connectivity.Tethering
import com.android.server.net.NetworkPolicyManagerInternal
import com.android.testutils.TestableNetworkCallback
import org.junit.After
@@ -169,8 +168,6 @@
val deps = spy(ConnectivityService.Dependencies())
doReturn(networkStackClient).`when`(deps).networkStack
doReturn(metricsLogger).`when`(deps).metricsLogger
- doReturn(mock(Tethering::class.java)).`when`(deps).makeTethering(
- any(), any(), any(), any(), any())
doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any())
doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties
doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager()
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index 5cb0d7e..e632aaf 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -22,8 +22,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import android.net.SocketKeepalive.InvalidPacketException;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 7ea9bcf..b2d363e 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -96,6 +96,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
@@ -197,6 +198,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.app.IBatteryStats;
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
@@ -210,7 +212,6 @@
import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.server.connectivity.ProxyTracker;
-import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal;
@@ -305,6 +306,7 @@
@Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
@Mock INetworkManagementService mNetworkManagementService;
@Mock INetworkStatsService mStatsService;
+ @Mock IBatteryStats mBatteryStatsService;
@Mock INetworkPolicyManager mNpm;
@Mock IDnsResolver mMockDnsResolver;
@Mock INetd mMockNetd;
@@ -1130,11 +1132,11 @@
doReturn(new TestNetIdManager()).when(deps).makeNetIdManager();
doReturn(mNetworkStack).when(deps).getNetworkStack();
doReturn(systemProperties).when(deps).getSystemProperties();
- doReturn(mock(Tethering.class)).when(deps).makeTethering(any(), any(), any(), any(), any());
doReturn(mock(ProxyTracker.class)).when(deps).makeProxyTracker(any(), any());
doReturn(mMetricsService).when(deps).getMetricsLogger();
doReturn(true).when(deps).queryUserAccess(anyInt(), anyInt());
doReturn(mIpConnectivityMetrics).when(deps).getIpConnectivityMetrics();
+ doReturn(mBatteryStatsService).when(deps).getBatteryStatsService();
doReturn(true).when(deps).hasService(Context.ETHERNET_SERVICE);
doAnswer(inv -> {
mPolicyTracker = new WrappedMultinetworkPolicyTracker(
@@ -3130,14 +3132,11 @@
.addTransportType(TRANSPORT_CELLULAR).build();
final TestNetworkCallback cellCallback = new TestNetworkCallback();
mCm.requestNetwork(cellRequest, cellCallback);
- // NOTE: This request causes the network's capabilities to change. This
- // is currently delivered before the onAvailable() callbacks.
- // TODO: Fix this.
- cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
cellCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
// Expect a network capabilities update with FOREGROUND, because the most recent
// request causes its state to change.
+ cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
assertTrue(isForegroundNetwork(mCellNetworkAgent));
assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
@@ -5640,6 +5639,37 @@
mCm.unregisterNetworkCallback(defaultCallback);
}
+ @Ignore // 40%+ flakiness : figure out why and re-enable.
+ @Test
+ public final void testBatteryStatsNetworkType() throws Exception {
+ final LinkProperties cellLp = new LinkProperties();
+ cellLp.setInterfaceName("cell0");
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
+ mCellNetworkAgent.connect(true);
+ waitForIdle();
+ verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(),
+ TYPE_MOBILE);
+ reset(mBatteryStatsService);
+
+ final LinkProperties wifiLp = new LinkProperties();
+ wifiLp.setInterfaceName("wifi0");
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp);
+ mWiFiNetworkAgent.connect(true);
+ waitForIdle();
+ verify(mBatteryStatsService).noteNetworkInterfaceType(wifiLp.getInterfaceName(),
+ TYPE_WIFI);
+ reset(mBatteryStatsService);
+
+ mCellNetworkAgent.disconnect();
+
+ cellLp.setInterfaceName("wifi0");
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
+ mCellNetworkAgent.connect(true);
+ waitForIdle();
+ verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(),
+ TYPE_MOBILE);
+ }
+
/**
* Make simulated InterfaceConfig for Nat464Xlat to query clat lower layer info.
*/
@@ -5680,25 +5710,28 @@
mCm.registerNetworkCallback(networkRequest, networkCallback);
// Prepare ipv6 only link properties.
- mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- final int cellNetId = mCellNetworkAgent.getNetwork().netId;
final LinkProperties cellLp = new LinkProperties();
cellLp.setInterfaceName(MOBILE_IFNAME);
cellLp.addLinkAddress(myIpv6);
cellLp.addRoute(new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME));
cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME));
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
reset(mNetworkManagementService);
reset(mMockDnsResolver);
reset(mMockNetd);
+ reset(mBatteryStatsService);
when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
.thenReturn(getClatInterfaceConfig(myIpv4));
// Connect with ipv6 link properties. Expect prefix discovery to be started.
- mCellNetworkAgent.sendLinkProperties(cellLp);
mCellNetworkAgent.connect(true);
+ final int cellNetId = mCellNetworkAgent.getNetwork().netId;
+ waitForIdle();
verify(mMockNetd, times(1)).networkCreatePhysical(eq(cellNetId), anyInt());
verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId));
+ verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(),
+ TYPE_MOBILE);
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
@@ -5714,6 +5747,11 @@
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
+ // Make sure BatteryStats was not told about any v4- interfaces, as none should have
+ // come online yet.
+ waitForIdle();
+ verify(mBatteryStatsService, never()).noteNetworkInterfaceType(startsWith("v4-"), anyInt());
+
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
reset(mMockNetd);
@@ -5760,6 +5798,11 @@
assertEquals(1, resolvrParams.servers.length);
assertTrue(ArrayUtils.contains(resolvrParams.servers, "8.8.8.8"));
+ for (final LinkProperties stackedLp : stackedLpsAfterChange) {
+ verify(mBatteryStatsService).noteNetworkInterfaceType(stackedLp.getInterfaceName(),
+ TYPE_MOBILE);
+ }
+
// Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
// linkproperties are cleaned up.
cellLp.addLinkAddress(myIpv4);
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index 2738daa..39f849c 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -265,6 +265,8 @@
assertFalse(mPermissionMonitor.hasNetworkPermission(app));
app = systemPackageInfoWithPermissions(CONNECTIVITY_USE_RESTRICTED_NETWORKS);
assertFalse(mPermissionMonitor.hasNetworkPermission(app));
+ app = systemPackageInfoWithPermissions(CONNECTIVITY_INTERNAL);
+ assertFalse(mPermissionMonitor.hasNetworkPermission(app));
}
@Test
@@ -274,7 +276,7 @@
PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
assertTrue(hasRestrictedNetworkPermission(
PARTITION_SYSTEM, VERSION_P, MOCK_UID1, NETWORK_STACK));
- assertTrue(hasRestrictedNetworkPermission(
+ assertFalse(hasRestrictedNetworkPermission(
PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
assertTrue(hasRestrictedNetworkPermission(
PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
@@ -283,7 +285,7 @@
assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
assertFalse(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_Q, MOCK_UID1, CHANGE_WIFI_STATE));
+ PARTITION_SYSTEM, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
}
@Test
@@ -291,14 +293,14 @@
doReturn(VERSION_P).when(mPermissionMonitor).getDeviceFirstSdkInt();
assertTrue(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
assertTrue(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CHANGE_WIFI_STATE));
+ PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_INTERNAL));
assertTrue(hasRestrictedNetworkPermission(
PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
doReturn(VERSION_Q).when(mPermissionMonitor).getDeviceFirstSdkInt();
assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
assertFalse(hasRestrictedNetworkPermission(
- PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CHANGE_WIFI_STATE));
+ PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_INTERNAL));
assertTrue(hasRestrictedNetworkPermission(
PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
}
@@ -319,7 +321,7 @@
assertFalse(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
assertFalse(hasRestrictedNetworkPermission(
- PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_WIFI_STATE));
+ PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
assertFalse(hasRestrictedNetworkPermission(
PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_NETWORK_STATE));
}
@@ -337,7 +339,7 @@
public void testHasUseBackgroundNetworksPermission() throws Exception {
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID);
- assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_WIFI_STATE);
+ assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL);
assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE);
assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK);
@@ -348,8 +350,9 @@
assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2);
- assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2,
+ assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2,
CONNECTIVITY_INTERNAL);
+ assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2, NETWORK_STACK);
}
private class NetdMonitor {