Merge master@5428150 into git_qt-dev-plus-aosp.
Change-Id: If790e058d4ec8a5024363b6aa1354a356c2f2d76 BUG: 129345239
This commit is contained in:
@@ -1934,6 +1934,8 @@ public class ConnectivityManager {
|
||||
@NonNull Callback callback) {
|
||||
ParcelFileDescriptor dup;
|
||||
try {
|
||||
// Dup is needed here as the pfd inside the socket is owned by the IpSecService,
|
||||
// which cannot be obtained by the app process.
|
||||
dup = ParcelFileDescriptor.dup(socket.getFileDescriptor());
|
||||
} catch (IOException ignored) {
|
||||
// Construct an invalid fd, so that if the user later calls start(), it will fail with
|
||||
@@ -1975,6 +1977,7 @@ public class ConnectivityManager {
|
||||
@NonNull Callback callback) {
|
||||
ParcelFileDescriptor dup;
|
||||
try {
|
||||
// TODO: Consider remove unnecessary dup.
|
||||
dup = pfd.dup();
|
||||
} catch (IOException ignored) {
|
||||
// Construct an invalid fd, so that if the user later calls start(), it will fail with
|
||||
@@ -3231,7 +3234,7 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void onPreCheck(Network network) {}
|
||||
public void onPreCheck(@NonNull Network network) {}
|
||||
|
||||
/**
|
||||
* Called when the framework connects and has declared a new network ready for use.
|
||||
@@ -3244,8 +3247,9 @@ public class ConnectivityManager {
|
||||
* @param blocked Whether access to the {@link Network} is blocked due to system policy.
|
||||
* @hide
|
||||
*/
|
||||
public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
|
||||
LinkProperties linkProperties, boolean blocked) {
|
||||
public void onAvailable(@NonNull Network network,
|
||||
@NonNull NetworkCapabilities networkCapabilities,
|
||||
@NonNull LinkProperties linkProperties, boolean blocked) {
|
||||
// Internally only this method is called when a new network is available, and
|
||||
// it calls the callback in the same way and order that older versions used
|
||||
// to call so as not to change the behavior.
|
||||
@@ -3269,7 +3273,7 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @param network The {@link Network} of the satisfying network.
|
||||
*/
|
||||
public void onAvailable(Network network) {}
|
||||
public void onAvailable(@NonNull Network network) {}
|
||||
|
||||
/**
|
||||
* Called when the network is about to be disconnected. Often paired with an
|
||||
@@ -3285,7 +3289,7 @@ public class ConnectivityManager {
|
||||
* network connected. Note that the network may suffer a
|
||||
* hard loss at any time.
|
||||
*/
|
||||
public void onLosing(Network network, int maxMsToLive) {}
|
||||
public void onLosing(@NonNull Network network, int maxMsToLive) {}
|
||||
|
||||
/**
|
||||
* Called when the framework has a hard loss of the network or when the
|
||||
@@ -3293,7 +3297,7 @@ public class ConnectivityManager {
|
||||
*
|
||||
* @param network The {@link Network} lost.
|
||||
*/
|
||||
public void onLost(Network network) {}
|
||||
public void onLost(@NonNull Network network) {}
|
||||
|
||||
/**
|
||||
* Called if no network is found in the timeout time specified in
|
||||
@@ -3313,8 +3317,8 @@ public class ConnectivityManager {
|
||||
* @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
|
||||
* network.
|
||||
*/
|
||||
public void onCapabilitiesChanged(Network network,
|
||||
NetworkCapabilities networkCapabilities) {}
|
||||
public void onCapabilitiesChanged(@NonNull Network network,
|
||||
@NonNull NetworkCapabilities networkCapabilities) {}
|
||||
|
||||
/**
|
||||
* Called when the network the framework connected to for this request
|
||||
@@ -3323,7 +3327,8 @@ public class ConnectivityManager {
|
||||
* @param network The {@link Network} whose link properties have changed.
|
||||
* @param linkProperties The new {@link LinkProperties} for this network.
|
||||
*/
|
||||
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
|
||||
public void onLinkPropertiesChanged(@NonNull Network network,
|
||||
@NonNull LinkProperties linkProperties) {}
|
||||
|
||||
/**
|
||||
* Called when the network the framework connected to for this request
|
||||
@@ -3334,7 +3339,7 @@ public class ConnectivityManager {
|
||||
* a tunnel, etc.
|
||||
* @hide
|
||||
*/
|
||||
public void onNetworkSuspended(Network network) {}
|
||||
public void onNetworkSuspended(@NonNull Network network) {}
|
||||
|
||||
/**
|
||||
* Called when the network the framework connected to for this request
|
||||
@@ -3342,7 +3347,7 @@ public class ConnectivityManager {
|
||||
* preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.
|
||||
* @hide
|
||||
*/
|
||||
public void onNetworkResumed(Network network) {}
|
||||
public void onNetworkResumed(@NonNull Network network) {}
|
||||
|
||||
/**
|
||||
* Called when access to the specified network is blocked or unblocked.
|
||||
|
||||
@@ -22,6 +22,10 @@ import static android.net.NetworkUtils.resNetworkResult;
|
||||
import static android.net.NetworkUtils.resNetworkSend;
|
||||
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
|
||||
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
|
||||
import static android.system.OsConstants.AF_INET;
|
||||
import static android.system.OsConstants.AF_INET6;
|
||||
import static android.system.OsConstants.IPPROTO_UDP;
|
||||
import static android.system.OsConstants.SOCK_DGRAM;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
@@ -30,12 +34,18 @@ import android.annotation.Nullable;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Looper;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -52,6 +62,7 @@ public final class DnsResolver {
|
||||
private static final String TAG = "DnsResolver";
|
||||
private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
|
||||
private static final int MAXPACKET = 8 * 1024;
|
||||
private static final int SLEEP_TIME_MS = 2;
|
||||
|
||||
@IntDef(prefix = { "CLASS_" }, value = {
|
||||
CLASS_IN
|
||||
@@ -188,9 +199,9 @@ public final class DnsResolver {
|
||||
* Send a raw DNS query.
|
||||
* The answer will be provided asynchronously through the provided {@link AnswerCallback}.
|
||||
*
|
||||
* @param network {@link Network} specifying which network for querying.
|
||||
* @param network {@link Network} specifying which network to query on.
|
||||
* {@code null} for query on default network.
|
||||
* @param query blob message
|
||||
* @param query blob message to query
|
||||
* @param flags flags as a combination of the FLAGS_* constants
|
||||
* @param executor The {@link Executor} that the callback should be executed on.
|
||||
* @param cancellationSignal used by the caller to signal if the query should be
|
||||
@@ -205,26 +216,32 @@ public final class DnsResolver {
|
||||
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
final Object lock = new Object();
|
||||
final FileDescriptor queryfd;
|
||||
try {
|
||||
queryfd = resNetworkSend((network != null
|
||||
? network.netId : NETID_UNSET), query, query.length, flags);
|
||||
} catch (ErrnoException e) {
|
||||
callback.onQueryException(e);
|
||||
executor.execute(() -> {
|
||||
callback.onQueryException(e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
maybeAddCancellationSignal(cancellationSignal, queryfd);
|
||||
registerFDListener(executor, queryfd, callback);
|
||||
synchronized (lock) {
|
||||
registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
|
||||
if (cancellationSignal == null) return;
|
||||
addCancellationSignal(cancellationSignal, queryfd, lock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DNS query with the specified name, class and query type.
|
||||
* The answer will be provided asynchronously through the provided {@link AnswerCallback}.
|
||||
*
|
||||
* @param network {@link Network} specifying which network for querying.
|
||||
* @param network {@link Network} specifying which network to query on.
|
||||
* {@code null} for query on default network.
|
||||
* @param domain domain name for querying
|
||||
* @param domain domain name to query
|
||||
* @param nsClass dns class as one of the CLASS_* constants
|
||||
* @param nsType dns resource record (RR) type as one of the TYPE_* constants
|
||||
* @param flags flags as a combination of the FLAGS_* constants
|
||||
@@ -242,40 +259,187 @@ public final class DnsResolver {
|
||||
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
final Object lock = new Object();
|
||||
final FileDescriptor queryfd;
|
||||
try {
|
||||
queryfd = resNetworkQuery((network != null
|
||||
? network.netId : NETID_UNSET), domain, nsClass, nsType, flags);
|
||||
} catch (ErrnoException e) {
|
||||
callback.onQueryException(e);
|
||||
executor.execute(() -> {
|
||||
callback.onQueryException(e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
synchronized (lock) {
|
||||
registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
|
||||
if (cancellationSignal == null) return;
|
||||
addCancellationSignal(cancellationSignal, queryfd, lock);
|
||||
}
|
||||
}
|
||||
|
||||
maybeAddCancellationSignal(cancellationSignal, queryfd);
|
||||
registerFDListener(executor, queryfd, callback);
|
||||
private class InetAddressAnswerAccumulator extends InetAddressAnswerCallback {
|
||||
private final List<InetAddress> mAllAnswers;
|
||||
private ParseException mParseException;
|
||||
private ErrnoException mErrnoException;
|
||||
private final InetAddressAnswerCallback mUserCallback;
|
||||
private final int mTargetAnswerCount;
|
||||
private int mReceivedAnswerCount = 0;
|
||||
|
||||
InetAddressAnswerAccumulator(int size, @NonNull InetAddressAnswerCallback callback) {
|
||||
mTargetAnswerCount = size;
|
||||
mAllAnswers = new ArrayList<>();
|
||||
mUserCallback = callback;
|
||||
}
|
||||
|
||||
private boolean maybeReportException() {
|
||||
if (mErrnoException != null) {
|
||||
mUserCallback.onQueryException(mErrnoException);
|
||||
return true;
|
||||
}
|
||||
if (mParseException != null) {
|
||||
mUserCallback.onParseException(mParseException);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void maybeReportAnswer() {
|
||||
if (++mReceivedAnswerCount != mTargetAnswerCount) return;
|
||||
if (mAllAnswers.isEmpty() && maybeReportException()) return;
|
||||
// TODO: Do RFC6724 sort.
|
||||
mUserCallback.onAnswer(mAllAnswers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnswer(@NonNull List<InetAddress> answer) {
|
||||
mAllAnswers.addAll(answer);
|
||||
maybeReportAnswer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onParseException(@NonNull ParseException e) {
|
||||
mParseException = e;
|
||||
maybeReportAnswer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueryException(@NonNull ErrnoException e) {
|
||||
mErrnoException = e;
|
||||
maybeReportAnswer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a DNS query with the specified name, get back a set of InetAddresses asynchronously.
|
||||
* The answer will be provided asynchronously through the provided
|
||||
* {@link InetAddressAnswerCallback}.
|
||||
*
|
||||
* @param network {@link Network} specifying which network to query on.
|
||||
* {@code null} for query on default network.
|
||||
* @param domain domain name to query
|
||||
* @param flags flags as a combination of the FLAGS_* constants
|
||||
* @param executor The {@link Executor} that the callback should be executed on.
|
||||
* @param cancellationSignal used by the caller to signal if the query should be
|
||||
* cancelled. May be {@code null}.
|
||||
* @param callback an {@link InetAddressAnswerCallback} which will be called to notify the
|
||||
* caller of the result of dns query.
|
||||
*/
|
||||
public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@Nullable CancellationSignal cancellationSignal,
|
||||
@NonNull InetAddressAnswerCallback callback) {
|
||||
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
final Object lock = new Object();
|
||||
final boolean queryIpv6 = haveIpv6(network);
|
||||
final boolean queryIpv4 = haveIpv4(network);
|
||||
|
||||
final FileDescriptor v4fd;
|
||||
final FileDescriptor v6fd;
|
||||
|
||||
int queryCount = 0;
|
||||
|
||||
if (queryIpv6) {
|
||||
try {
|
||||
v6fd = resNetworkQuery((network != null
|
||||
? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_AAAA, flags);
|
||||
} catch (ErrnoException e) {
|
||||
executor.execute(() -> {
|
||||
callback.onQueryException(e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
queryCount++;
|
||||
} else v6fd = null;
|
||||
|
||||
// TODO: Use device flag to control the sleep time.
|
||||
// Avoiding gateways drop packets if queries are sent too close together
|
||||
try {
|
||||
Thread.sleep(SLEEP_TIME_MS);
|
||||
} catch (InterruptedException ex) { }
|
||||
|
||||
if (queryIpv4) {
|
||||
try {
|
||||
v4fd = resNetworkQuery((network != null
|
||||
? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_A, flags);
|
||||
} catch (ErrnoException e) {
|
||||
if (queryIpv6) resNetworkCancel(v6fd); // Closes fd, marks it invalid.
|
||||
executor.execute(() -> {
|
||||
callback.onQueryException(e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
queryCount++;
|
||||
} else v4fd = null;
|
||||
|
||||
final InetAddressAnswerAccumulator accumulator =
|
||||
new InetAddressAnswerAccumulator(queryCount, callback);
|
||||
|
||||
synchronized (lock) {
|
||||
if (queryIpv6) {
|
||||
registerFDListener(executor, v6fd, accumulator, cancellationSignal, lock);
|
||||
}
|
||||
if (queryIpv4) {
|
||||
registerFDListener(executor, v4fd, accumulator, cancellationSignal, lock);
|
||||
}
|
||||
if (cancellationSignal == null) return;
|
||||
cancellationSignal.setOnCancelListener(() -> {
|
||||
synchronized (lock) {
|
||||
if (queryIpv4) cancelQuery(v4fd);
|
||||
if (queryIpv6) cancelQuery(v6fd);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void registerFDListener(@NonNull Executor executor,
|
||||
@NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback) {
|
||||
@NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback,
|
||||
@Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
|
||||
Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
|
||||
queryfd,
|
||||
FD_EVENTS,
|
||||
(fd, events) -> {
|
||||
executor.execute(() -> {
|
||||
byte[] answerbuf = null;
|
||||
try {
|
||||
answerbuf = resNetworkResult(fd);
|
||||
} catch (ErrnoException e) {
|
||||
Log.e(TAG, "resNetworkResult:" + e.toString());
|
||||
answerCallback.onQueryException(e);
|
||||
return;
|
||||
}
|
||||
synchronized (lock) {
|
||||
if (cancellationSignal != null && cancellationSignal.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
byte[] answerbuf = null;
|
||||
try {
|
||||
answerbuf = resNetworkResult(fd); // Closes fd, marks it invalid.
|
||||
} catch (ErrnoException e) {
|
||||
Log.e(TAG, "resNetworkResult:" + e.toString());
|
||||
answerCallback.onQueryException(e);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
answerCallback.onAnswer(
|
||||
answerCallback.parser.parse(answerbuf));
|
||||
} catch (ParseException e) {
|
||||
answerCallback.onParseException(e);
|
||||
try {
|
||||
answerCallback.onAnswer(
|
||||
answerCallback.parser.parse(answerbuf));
|
||||
} catch (ParseException e) {
|
||||
answerCallback.onParseException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
// Unregister this fd listener
|
||||
@@ -283,15 +447,51 @@ public final class DnsResolver {
|
||||
});
|
||||
}
|
||||
|
||||
private void maybeAddCancellationSignal(@Nullable CancellationSignal cancellationSignal,
|
||||
@NonNull FileDescriptor queryfd) {
|
||||
if (cancellationSignal == null) return;
|
||||
cancellationSignal.setOnCancelListener(
|
||||
() -> {
|
||||
Looper.getMainLooper().getQueue()
|
||||
.removeOnFileDescriptorEventListener(queryfd);
|
||||
resNetworkCancel(queryfd);
|
||||
});
|
||||
private void cancelQuery(@NonNull FileDescriptor queryfd) {
|
||||
if (!queryfd.valid()) return;
|
||||
Looper.getMainLooper().getQueue().removeOnFileDescriptorEventListener(queryfd);
|
||||
resNetworkCancel(queryfd); // Closes fd, marks it invalid.
|
||||
}
|
||||
|
||||
private void addCancellationSignal(@NonNull CancellationSignal cancellationSignal,
|
||||
@NonNull FileDescriptor queryfd, @NonNull Object lock) {
|
||||
cancellationSignal.setOnCancelListener(() -> {
|
||||
synchronized (lock) {
|
||||
cancelQuery(queryfd);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// These two functions match the behaviour of have_ipv4 and have_ipv6 in the native resolver.
|
||||
private boolean haveIpv4(@Nullable Network network) {
|
||||
final SocketAddress addrIpv4 =
|
||||
new InetSocketAddress(InetAddresses.parseNumericAddress("8.8.8.8"), 0);
|
||||
return checkConnectivity(network, AF_INET, addrIpv4);
|
||||
}
|
||||
|
||||
private boolean haveIpv6(@Nullable Network network) {
|
||||
final SocketAddress addrIpv6 =
|
||||
new InetSocketAddress(InetAddresses.parseNumericAddress("2000::"), 0);
|
||||
return checkConnectivity(network, AF_INET6, addrIpv6);
|
||||
}
|
||||
|
||||
private boolean checkConnectivity(@Nullable Network network,
|
||||
int domain, @NonNull SocketAddress addr) {
|
||||
final FileDescriptor socket;
|
||||
try {
|
||||
socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP);
|
||||
} catch (ErrnoException e) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (network != null) network.bindSocket(socket);
|
||||
Os.connect(socket, addr);
|
||||
} catch (IOException | ErrnoException e) {
|
||||
return false;
|
||||
} finally {
|
||||
IoUtils.closeQuietly(socket);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class DnsAddressAnswer extends DnsPacket {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
@@ -71,7 +72,7 @@ public final class IpPrefix implements Parcelable {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public IpPrefix(@NonNull byte[] address, int prefixLength) {
|
||||
public IpPrefix(@NonNull byte[] address, @IntRange(from = 0, to = 128) int prefixLength) {
|
||||
this.address = address.clone();
|
||||
this.prefixLength = prefixLength;
|
||||
checkAndMaskAddressAndPrefixLength();
|
||||
@@ -88,7 +89,7 @@ public final class IpPrefix implements Parcelable {
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public IpPrefix(@NonNull InetAddress address, int prefixLength) {
|
||||
public IpPrefix(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength) {
|
||||
// We don't reuse the (byte[], int) constructor because it calls clone() on the byte array,
|
||||
// which is unnecessary because getAddress() already returns a clone.
|
||||
this.address = address.getAddress();
|
||||
@@ -150,13 +151,13 @@ public final class IpPrefix implements Parcelable {
|
||||
*
|
||||
* @return the address in the form of a byte array.
|
||||
*/
|
||||
public InetAddress getAddress() {
|
||||
public @NonNull InetAddress getAddress() {
|
||||
try {
|
||||
return InetAddress.getByAddress(address);
|
||||
} catch (UnknownHostException e) {
|
||||
// Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
|
||||
// array is the wrong length, but we check that in the constructor.
|
||||
return null;
|
||||
throw new IllegalArgumentException("Address is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +167,7 @@ public final class IpPrefix implements Parcelable {
|
||||
*
|
||||
* @return the address in the form of a byte array.
|
||||
*/
|
||||
public byte[] getRawAddress() {
|
||||
public @NonNull byte[] getRawAddress() {
|
||||
return address.clone();
|
||||
}
|
||||
|
||||
@@ -175,6 +176,7 @@ public final class IpPrefix implements Parcelable {
|
||||
*
|
||||
* @return the prefix length.
|
||||
*/
|
||||
@IntRange(from = 0, to = 128)
|
||||
public int getPrefixLength() {
|
||||
return prefixLength;
|
||||
}
|
||||
@@ -183,10 +185,10 @@ public final class IpPrefix implements Parcelable {
|
||||
* Determines whether the prefix contains the specified address.
|
||||
*
|
||||
* @param address An {@link InetAddress} to test.
|
||||
* @return {@code true} if the prefix covers the given address.
|
||||
* @return {@code true} if the prefix covers the given address. {@code false} otherwise.
|
||||
*/
|
||||
public boolean contains(InetAddress address) {
|
||||
byte[] addrBytes = (address == null) ? null : address.getAddress();
|
||||
public boolean contains(@NonNull InetAddress address) {
|
||||
byte[] addrBytes = address.getAddress();
|
||||
if (addrBytes == null || addrBytes.length != this.address.length) {
|
||||
return false;
|
||||
}
|
||||
@@ -201,7 +203,7 @@ public final class IpPrefix implements Parcelable {
|
||||
* @param otherPrefix the prefix to test
|
||||
* @hide
|
||||
*/
|
||||
public boolean containsPrefix(IpPrefix otherPrefix) {
|
||||
public boolean containsPrefix(@NonNull IpPrefix otherPrefix) {
|
||||
if (otherPrefix.getPrefixLength() < prefixLength) return false;
|
||||
final byte[] otherAddress = otherPrefix.getRawAddress();
|
||||
NetworkUtils.maskRawAddress(otherAddress, prefixLength);
|
||||
|
||||
@@ -25,6 +25,7 @@ import static android.system.OsConstants.RT_SCOPE_LINK;
|
||||
import static android.system.OsConstants.RT_SCOPE_SITE;
|
||||
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
@@ -170,7 +171,7 @@ public class LinkAddress implements Parcelable {
|
||||
* Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with
|
||||
* the specified flags and scope. Flags and scope are not checked for validity.
|
||||
* @param address The IP address.
|
||||
* @param prefixLength The prefix length.
|
||||
* @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
|
||||
* @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
|
||||
* @param scope An integer defining the scope in which the address is unique (e.g.,
|
||||
* {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
|
||||
@@ -178,7 +179,8 @@ public class LinkAddress implements Parcelable {
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) {
|
||||
public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
|
||||
int flags, int scope) {
|
||||
init(address, prefixLength, flags, scope);
|
||||
}
|
||||
|
||||
@@ -186,12 +188,13 @@ public class LinkAddress implements Parcelable {
|
||||
* Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length.
|
||||
* The flags are set to zero and the scope is determined from the address.
|
||||
* @param address The IP address.
|
||||
* @param prefixLength The prefix length.
|
||||
* @param prefixLength The prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public LinkAddress(@NonNull InetAddress address, int prefixLength) {
|
||||
public LinkAddress(@NonNull InetAddress address,
|
||||
@IntRange(from = 0, to = 128) int prefixLength) {
|
||||
this(address, prefixLength, 0, 0);
|
||||
this.scope = scopeForUnicastAddress(address);
|
||||
}
|
||||
@@ -202,7 +205,7 @@ public class LinkAddress implements Parcelable {
|
||||
* @param interfaceAddress The interface address.
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress(InterfaceAddress interfaceAddress) {
|
||||
public LinkAddress(@NonNull InterfaceAddress interfaceAddress) {
|
||||
this(interfaceAddress.getAddress(),
|
||||
interfaceAddress.getNetworkPrefixLength());
|
||||
}
|
||||
@@ -306,6 +309,7 @@ public class LinkAddress implements Parcelable {
|
||||
/**
|
||||
* Returns the prefix length of this {@code LinkAddress}.
|
||||
*/
|
||||
@IntRange(from = 0, to = 128)
|
||||
public int getPrefixLength() {
|
||||
return prefixLength;
|
||||
}
|
||||
@@ -316,6 +320,7 @@ public class LinkAddress implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@IntRange(from = 0, to = 128)
|
||||
public int getNetworkPrefixLength() {
|
||||
return getPrefixLength();
|
||||
}
|
||||
|
||||
@@ -316,9 +316,6 @@ public final class LinkProperties implements Parcelable {
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public boolean removeLinkAddress(@NonNull LinkAddress toRemove) {
|
||||
if (toRemove == null) {
|
||||
return false;
|
||||
}
|
||||
int i = findLinkAddressIndex(toRemove);
|
||||
if (i >= 0) {
|
||||
mLinkAddresses.remove(i);
|
||||
@@ -391,10 +388,7 @@ public final class LinkProperties implements Parcelable {
|
||||
@TestApi
|
||||
@SystemApi
|
||||
public boolean removeDnsServer(@NonNull InetAddress dnsServer) {
|
||||
if (dnsServer != null) {
|
||||
return mDnses.remove(dnsServer);
|
||||
}
|
||||
return false;
|
||||
return mDnses.remove(dnsServer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.net;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.net.NetworkCapabilities.NetCapability;
|
||||
@@ -343,10 +344,14 @@ public class NetworkRequest implements Parcelable {
|
||||
* current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
|
||||
* received and has no effect when requesting a callback.
|
||||
*
|
||||
* <p>This method requires the caller to hold the
|
||||
* {@link android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP} permission
|
||||
*
|
||||
* @param signalStrength the bearer-specific signal strength.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
|
||||
public @NonNull Builder setSignalStrength(int signalStrength) {
|
||||
mNetworkCapabilities.setSignalStrength(signalStrength);
|
||||
return this;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
@@ -24,6 +26,8 @@ import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
@@ -51,20 +55,32 @@ import java.util.Objects;
|
||||
* (IPv4 or IPv6).
|
||||
*/
|
||||
public final class RouteInfo implements Parcelable {
|
||||
/** @hide */
|
||||
@IntDef(value = {
|
||||
RTN_UNICAST,
|
||||
RTN_UNREACHABLE,
|
||||
RTN_THROW,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface RouteType {}
|
||||
|
||||
/**
|
||||
* The IP destination address for this route.
|
||||
*/
|
||||
@NonNull
|
||||
private final IpPrefix mDestination;
|
||||
|
||||
/**
|
||||
* The gateway address for this route.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@Nullable
|
||||
private final InetAddress mGateway;
|
||||
|
||||
/**
|
||||
* The interface for this route.
|
||||
*/
|
||||
@Nullable
|
||||
private final String mInterface;
|
||||
|
||||
|
||||
@@ -108,13 +124,14 @@ public final class RouteInfo implements Parcelable {
|
||||
* @param destination the destination prefix
|
||||
* @param gateway the IP address to route packets through
|
||||
* @param iface the interface name to send packets on
|
||||
* @param type the type of this route
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@TestApi
|
||||
public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
|
||||
@Nullable String iface, int type) {
|
||||
@Nullable String iface, @RouteType int type) {
|
||||
switch (type) {
|
||||
case RTN_UNICAST:
|
||||
case RTN_UNREACHABLE:
|
||||
@@ -173,10 +190,24 @@ public final class RouteInfo implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Constructs a {@code RouteInfo} object.
|
||||
*
|
||||
* If destination is null, then gateway must be specified and the
|
||||
* constructed route is either the IPv4 default route <code>0.0.0.0</code>
|
||||
* if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
|
||||
* route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
|
||||
* <p>
|
||||
* Destination and gateway may not both be null.
|
||||
*
|
||||
* @param destination the destination address and prefix in an {@link IpPrefix}
|
||||
* @param gateway the {@link InetAddress} to route packets through
|
||||
* @param iface the interface name to send packets on
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
|
||||
public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
|
||||
@Nullable String iface) {
|
||||
this(destination, gateway, iface, RTN_UNICAST);
|
||||
}
|
||||
|
||||
@@ -184,7 +215,8 @@ public final class RouteInfo implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
|
||||
public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway,
|
||||
@Nullable String iface) {
|
||||
this(destination == null ? null :
|
||||
new IpPrefix(destination.getAddress(), destination.getPrefixLength()),
|
||||
gateway, iface);
|
||||
@@ -205,7 +237,7 @@ public final class RouteInfo implements Parcelable {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination, InetAddress gateway) {
|
||||
public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway) {
|
||||
this(destination, gateway, null);
|
||||
}
|
||||
|
||||
@@ -215,7 +247,7 @@ public final class RouteInfo implements Parcelable {
|
||||
* TODO: Remove this.
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public RouteInfo(LinkAddress destination, InetAddress gateway) {
|
||||
public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway) {
|
||||
this(destination, gateway, null);
|
||||
}
|
||||
|
||||
@@ -227,7 +259,7 @@ public final class RouteInfo implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public RouteInfo(InetAddress gateway) {
|
||||
public RouteInfo(@NonNull InetAddress gateway) {
|
||||
this((IpPrefix) null, gateway, null);
|
||||
}
|
||||
|
||||
@@ -239,35 +271,36 @@ public final class RouteInfo implements Parcelable {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination) {
|
||||
public RouteInfo(@NonNull IpPrefix destination) {
|
||||
this(destination, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(LinkAddress destination) {
|
||||
public RouteInfo(@NonNull LinkAddress destination) {
|
||||
this(destination, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination, int type) {
|
||||
public RouteInfo(@NonNull IpPrefix destination, @RouteType int type) {
|
||||
this(destination, null, null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static RouteInfo makeHostRoute(InetAddress host, String iface) {
|
||||
public static RouteInfo makeHostRoute(@NonNull InetAddress host, @Nullable String iface) {
|
||||
return makeHostRoute(host, null, iface);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) {
|
||||
public static RouteInfo makeHostRoute(@Nullable InetAddress host, @Nullable InetAddress gateway,
|
||||
@Nullable String iface) {
|
||||
if (host == null) return null;
|
||||
|
||||
if (host instanceof Inet4Address) {
|
||||
@@ -290,6 +323,7 @@ public final class RouteInfo implements Parcelable {
|
||||
*
|
||||
* @return {@link IpPrefix} specifying the destination. This is never {@code null}.
|
||||
*/
|
||||
@NonNull
|
||||
public IpPrefix getDestination() {
|
||||
return mDestination;
|
||||
}
|
||||
@@ -298,6 +332,7 @@ public final class RouteInfo implements Parcelable {
|
||||
* TODO: Convert callers to use IpPrefix and then remove.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public LinkAddress getDestinationLinkAddress() {
|
||||
return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength());
|
||||
}
|
||||
@@ -308,6 +343,7 @@ public final class RouteInfo implements Parcelable {
|
||||
* @return {@link InetAddress} specifying the gateway or next hop. This may be
|
||||
* {@code null} for a directly-connected route."
|
||||
*/
|
||||
@Nullable
|
||||
public InetAddress getGateway() {
|
||||
return mGateway;
|
||||
}
|
||||
@@ -317,6 +353,7 @@ public final class RouteInfo implements Parcelable {
|
||||
*
|
||||
* @return The name of the interface used for this route.
|
||||
*/
|
||||
@Nullable
|
||||
public String getInterface() {
|
||||
return mInterface;
|
||||
}
|
||||
@@ -330,6 +367,7 @@ public final class RouteInfo implements Parcelable {
|
||||
*/
|
||||
@TestApi
|
||||
@SystemApi
|
||||
@RouteType
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
@@ -401,6 +439,7 @@ public final class RouteInfo implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@Nullable
|
||||
public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
|
||||
if ((routes == null) || (dest == null)) return null;
|
||||
|
||||
|
||||
@@ -19,14 +19,17 @@ package android.net.apf;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
/**
|
||||
* APF program support capabilities.
|
||||
* APF program support capabilities. APF stands for Android Packet Filtering and it is a flexible
|
||||
* way to drop unwanted network packets to save power.
|
||||
*
|
||||
* See documentation at hardware/google/apf/apf.h
|
||||
*
|
||||
* This class is immutable.
|
||||
* @hide
|
||||
@@ -104,10 +107,11 @@ public final class ApfCapabilities implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the APF interpreter advertises support for the data buffer access opcodes
|
||||
* LDDW and STDW.
|
||||
* Determines whether the APF interpreter advertises support for the data buffer access opcodes
|
||||
* LDDW (LoaD Data Word) and STDW (STore Data Word). Full LDDW (LoaD Data Word) and
|
||||
* STDW (STore Data Word) support is present from APFv4 on.
|
||||
*
|
||||
* Full LDDW and STDW support is present from APFv4 on.
|
||||
* @return {@code true} if the IWifiStaIface#readApfPacketFilterData is supported.
|
||||
*/
|
||||
public boolean hasDataAccess() {
|
||||
return apfVersionSupported >= 4;
|
||||
@@ -116,14 +120,14 @@ public final class ApfCapabilities implements Parcelable {
|
||||
/**
|
||||
* @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames.
|
||||
*/
|
||||
public static boolean getApfDrop8023Frames(@NonNull Context context) {
|
||||
return context.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);
|
||||
public static boolean getApfDrop8023Frames() {
|
||||
return Resources.getSystem().getBoolean(R.bool.config_apfDrop802_3Frames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An array of blacklisted EtherType, packets with EtherTypes within it will be dropped.
|
||||
*/
|
||||
public static @NonNull int[] getApfEthTypeBlackList(@NonNull Context context) {
|
||||
return context.getResources().getIntArray(R.array.config_apfEthTypeBlackList);
|
||||
public static @NonNull int[] getApfEtherTypeBlackList() {
|
||||
return Resources.getSystem().getIntArray(R.array.config_apfEthTypeBlackList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,6 +470,7 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz,
|
||||
std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
|
||||
|
||||
int res = resNetworkResult(fd, &rcode, buf.data(), MAXPACKETSIZE);
|
||||
jniSetFileDescriptorOfFD(env, javaFd, -1);
|
||||
if (res < 0) {
|
||||
throwErrnoException(env, "resNetworkResult", -res);
|
||||
return nullptr;
|
||||
@@ -490,6 +491,7 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz,
|
||||
static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
|
||||
int fd = jniGetFDFromFileDescriptor(env, javaFd);
|
||||
resNetworkCancel(fd);
|
||||
jniSetFileDescriptorOfFD(env, javaFd, -1);
|
||||
}
|
||||
|
||||
static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
|
||||
|
||||
@@ -63,6 +63,7 @@ import android.net.ConnectionInfo;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.ICaptivePortal;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.IIpConnectivityMetrics;
|
||||
import android.net.INetd;
|
||||
import android.net.INetdEventCallback;
|
||||
@@ -294,6 +295,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
private INetworkManagementService mNMS;
|
||||
@VisibleForTesting
|
||||
protected IDnsResolver mDnsResolver;
|
||||
@VisibleForTesting
|
||||
protected INetd mNetd;
|
||||
private INetworkStatsService mStatsService;
|
||||
private INetworkPolicyManager mPolicyManager;
|
||||
@@ -525,6 +528,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return sMagicDecoderRing.get(what, Integer.toString(what));
|
||||
}
|
||||
|
||||
private static IDnsResolver getDnsResolver() {
|
||||
return IDnsResolver.Stub
|
||||
.asInterface(ServiceManager.getService("dnsresolver"));
|
||||
}
|
||||
|
||||
/** Handler thread used for both of the handlers below. */
|
||||
@VisibleForTesting
|
||||
protected final HandlerThread mHandlerThread;
|
||||
@@ -810,13 +818,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
public ConnectivityService(Context context, INetworkManagementService netManager,
|
||||
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
|
||||
this(context, netManager, statsService, policyManager, new IpConnectivityLog());
|
||||
this(context, netManager, statsService, policyManager,
|
||||
getDnsResolver(), new IpConnectivityLog());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected ConnectivityService(Context context, INetworkManagementService netManager,
|
||||
INetworkStatsService statsService, INetworkPolicyManager policyManager,
|
||||
IpConnectivityLog logger) {
|
||||
IDnsResolver dnsresolver, IpConnectivityLog logger) {
|
||||
if (DBG) log("ConnectivityService starting up");
|
||||
|
||||
mSystemProperties = getSystemProperties();
|
||||
@@ -853,6 +862,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mPolicyManagerInternal = checkNotNull(
|
||||
LocalServices.getService(NetworkPolicyManagerInternal.class),
|
||||
"missing NetworkPolicyManagerInternal");
|
||||
mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
|
||||
mProxyTracker = makeProxyTracker();
|
||||
|
||||
mNetd = NetdService.getInstance();
|
||||
@@ -1006,7 +1016,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
|
||||
|
||||
mDnsManager = new DnsManager(mContext, mNMS, mSystemProperties);
|
||||
mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties);
|
||||
registerPrivateDnsSettingsCallbacks();
|
||||
}
|
||||
|
||||
@@ -1882,6 +1892,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) {
|
||||
for (String permission : permissions) {
|
||||
if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void enforceAnyPermissionOf(String... permissions) {
|
||||
if (!checkAnyPermissionOf(permissions)) {
|
||||
throw new SecurityException("Requires one of the following permissions: "
|
||||
@@ -1956,6 +1975,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
|
||||
}
|
||||
|
||||
private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) {
|
||||
return checkAnyPermissionOf(pid, uid,
|
||||
android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
|
||||
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
|
||||
}
|
||||
|
||||
private void enforceConnectivityRestrictedNetworksPermission() {
|
||||
try {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
@@ -3021,9 +3046,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// NetworkFactories, so network traffic isn't interrupted for an unnecessarily
|
||||
// long time.
|
||||
try {
|
||||
mNMS.removeNetwork(nai.network.netId);
|
||||
} catch (Exception e) {
|
||||
loge("Exception removing network: " + e);
|
||||
mNetd.networkDestroy(nai.network.netId);
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
loge("Exception destroying network: " + e);
|
||||
}
|
||||
mDnsManager.removeNetwork(nai.network);
|
||||
}
|
||||
@@ -3728,16 +3753,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
break;
|
||||
}
|
||||
case EVENT_SYSTEM_READY: {
|
||||
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
||||
// Might have been called already in handleRegisterNetworkAgent since
|
||||
// mSystemReady is set before sending EVENT_SYSTEM_READY, but calling
|
||||
// this several times is fine.
|
||||
try {
|
||||
nai.networkMonitor().notifySystemReady();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
mMultipathPolicyTracker.start();
|
||||
break;
|
||||
}
|
||||
@@ -4952,13 +4967,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
// This checks that the passed capabilities either do not request a specific SSID, or the
|
||||
// calling app has permission to do so.
|
||||
// This checks that the passed capabilities either do not request a specific SSID/SignalStrength
|
||||
// , or the calling app has permission to do so.
|
||||
private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
|
||||
int callerPid, int callerUid) {
|
||||
if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
|
||||
throw new SecurityException("Insufficient permissions to request a specific SSID");
|
||||
}
|
||||
|
||||
if (nc.hasSignalStrength()
|
||||
&& !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
|
||||
throw new SecurityException(
|
||||
"Insufficient permissions to request a specific signal strength");
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
|
||||
@@ -5372,10 +5393,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
||||
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
|
||||
new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
|
||||
mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mNMS,
|
||||
factorySerialNumber);
|
||||
mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver,
|
||||
mNMS, factorySerialNumber);
|
||||
// Make sure the network capabilities reflect what the agent info says.
|
||||
nai.networkCapabilities = mixInCapabilities(nai, nc);
|
||||
nai.setNetworkCapabilities(mixInCapabilities(nai, nc));
|
||||
final String extraInfo = networkInfo.getExtraInfo();
|
||||
final String name = TextUtils.isEmpty(extraInfo)
|
||||
? nai.networkCapabilities.getSSID() : extraInfo;
|
||||
@@ -5406,15 +5427,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
synchronized (mNetworkForNetId) {
|
||||
mNetworkForNetId.put(nai.network.netId, nai);
|
||||
}
|
||||
synchronized (this) {
|
||||
if (mSystemReady) {
|
||||
try {
|
||||
networkMonitor.notifySystemReady();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
networkMonitor.start();
|
||||
@@ -5468,12 +5480,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// Start or stop DNS64 detection and 464xlat according to network state.
|
||||
networkAgent.clatd.update();
|
||||
notifyIfacesChangedForNetworkStats();
|
||||
try {
|
||||
networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
if (networkAgent.everConnected) {
|
||||
try {
|
||||
networkAgent.networkMonitor().notifyLinkPropertiesChanged();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
|
||||
}
|
||||
}
|
||||
@@ -5701,7 +5713,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
final NetworkCapabilities prevNc;
|
||||
synchronized (nai) {
|
||||
prevNc = nai.networkCapabilities;
|
||||
nai.networkCapabilities = newNc;
|
||||
nai.setNetworkCapabilities(newNc);
|
||||
}
|
||||
|
||||
updateUids(nai, prevNc, newNc);
|
||||
@@ -5716,11 +5728,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// 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.
|
||||
rematchAllNetworksAndRequests(nai, oldScore);
|
||||
try {
|
||||
nai.networkMonitor().notifyNetworkCapabilitiesChanged();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
|
||||
}
|
||||
|
||||
@@ -5979,11 +5986,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
|
||||
if (capabilitiesChanged) {
|
||||
try {
|
||||
nai.networkMonitor().notifyNetworkCapabilitiesChanged();
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
|
||||
}
|
||||
|
||||
@@ -6392,7 +6394,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (networkAgent.networkMisc.acceptPartialConnectivity) {
|
||||
networkAgent.networkMonitor().setAcceptPartialConnectivity();
|
||||
}
|
||||
networkAgent.networkMonitor().notifyNetworkConnected();
|
||||
networkAgent.networkMonitor().notifyNetworkConnected(
|
||||
networkAgent.linkProperties, networkAgent.networkCapabilities);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -30,13 +30,15 @@ import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkUtils;
|
||||
import android.net.Uri;
|
||||
import android.net.shared.PrivateDnsConfig;
|
||||
import android.os.Binder;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
@@ -229,7 +231,7 @@ public class DnsManager {
|
||||
|
||||
private final Context mContext;
|
||||
private final ContentResolver mContentResolver;
|
||||
private final INetworkManagementService mNMS;
|
||||
private final IDnsResolver mDnsResolver;
|
||||
private final MockableSystemProperties mSystemProperties;
|
||||
// TODO: Replace these Maps with SparseArrays.
|
||||
private final Map<Integer, PrivateDnsConfig> mPrivateDnsMap;
|
||||
@@ -243,10 +245,10 @@ public class DnsManager {
|
||||
private String mPrivateDnsMode;
|
||||
private String mPrivateDnsSpecifier;
|
||||
|
||||
public DnsManager(Context ctx, INetworkManagementService nms, MockableSystemProperties sp) {
|
||||
public DnsManager(Context ctx, IDnsResolver dnsResolver, MockableSystemProperties sp) {
|
||||
mContext = ctx;
|
||||
mContentResolver = mContext.getContentResolver();
|
||||
mNMS = nms;
|
||||
mDnsResolver = dnsResolver;
|
||||
mSystemProperties = sp;
|
||||
mPrivateDnsMap = new HashMap<>();
|
||||
mPrivateDnsValidationMap = new HashMap<>();
|
||||
@@ -260,6 +262,12 @@ public class DnsManager {
|
||||
}
|
||||
|
||||
public void removeNetwork(Network network) {
|
||||
try {
|
||||
mDnsResolver.clearResolverConfiguration(network.netId);
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
Slog.e(TAG, "Error clearing DNS configuration: " + e);
|
||||
return;
|
||||
}
|
||||
mPrivateDnsMap.remove(network.netId);
|
||||
mPrivateDnsValidationMap.remove(network.netId);
|
||||
}
|
||||
@@ -344,10 +352,12 @@ public class DnsManager {
|
||||
Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %s, %s, %s)",
|
||||
netId, Arrays.toString(assignedServers), Arrays.toString(domainStrs),
|
||||
Arrays.toString(params), tlsHostname, Arrays.toString(tlsServers)));
|
||||
final String[] tlsFingerprints = new String[0];
|
||||
try {
|
||||
mNMS.setDnsConfigurationForNetwork(
|
||||
netId, assignedServers, domainStrs, params, tlsHostname, tlsServers);
|
||||
} catch (Exception e) {
|
||||
mDnsResolver.setResolverConfiguration(
|
||||
netId, assignedServers, domainStrs, params,
|
||||
tlsHostname, tlsServers, tlsFingerprints);
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
Slog.e(TAG, "Error setting DNS configuration: " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ public class KeepaliveTracker {
|
||||
private static final int NOT_STARTED = 1;
|
||||
private static final int STARTING = 2;
|
||||
private static final int STARTED = 3;
|
||||
private static final int STOPPING = 4;
|
||||
private int mStartedState = NOT_STARTED;
|
||||
|
||||
KeepaliveInfo(@NonNull ISocketKeepaliveCallback callback,
|
||||
@@ -154,12 +155,19 @@ public class KeepaliveTracker {
|
||||
// keepalives are sent cannot be reused by another app even if the fd gets closed by
|
||||
// the user. A null is acceptable here for backward compatibility of PacketKeepalive
|
||||
// API.
|
||||
// TODO: don't accept null fd after legacy packetKeepalive API is removed.
|
||||
try {
|
||||
if (fd != null) {
|
||||
mFd = Os.dup(fd);
|
||||
} else {
|
||||
Log.d(TAG, "uid/pid " + mUid + "/" + mPid + " calls with null fd");
|
||||
Log.d(TAG, toString() + " calls with null fd");
|
||||
if (!mPrivileged) {
|
||||
throw new SecurityException(
|
||||
"null fd is not allowed for unprivileged access.");
|
||||
}
|
||||
if (mType == TYPE_TCP) {
|
||||
throw new IllegalArgumentException(
|
||||
"null fd is not allowed for tcp socket keepalives.");
|
||||
}
|
||||
mFd = null;
|
||||
}
|
||||
} catch (ErrnoException e) {
|
||||
@@ -307,6 +315,7 @@ public class KeepaliveTracker {
|
||||
}
|
||||
}
|
||||
if (NOT_STARTED != mStartedState) {
|
||||
mStartedState = STOPPING;
|
||||
Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.name());
|
||||
if (mType == TYPE_NATT) {
|
||||
mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
|
||||
@@ -449,8 +458,8 @@ public class KeepaliveTracker {
|
||||
ki = mKeepalives.get(nai).get(slot);
|
||||
} catch(NullPointerException e) {}
|
||||
if (ki == null) {
|
||||
Log.e(TAG, "Event " + message.what + " for unknown keepalive " + slot + " on "
|
||||
+ nai.name());
|
||||
Log.e(TAG, "Event " + message.what + "," + slot + "," + reason
|
||||
+ " for unknown keepalive " + slot + " on " + nai.name());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -469,27 +478,30 @@ public class KeepaliveTracker {
|
||||
// messages in order.
|
||||
// TODO : clarify this code and get rid of mStartedState. Using a StateMachine is an
|
||||
// option.
|
||||
if (reason == SUCCESS && KeepaliveInfo.STARTING == ki.mStartedState) {
|
||||
// Keepalive successfully started.
|
||||
if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
|
||||
ki.mStartedState = KeepaliveInfo.STARTED;
|
||||
try {
|
||||
ki.mCallback.onStarted(slot);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Discarded onStarted(" + slot + ") callback");
|
||||
}
|
||||
} else {
|
||||
// Keepalive successfully stopped, or error.
|
||||
ki.mStartedState = KeepaliveInfo.NOT_STARTED;
|
||||
if (reason == SUCCESS) {
|
||||
// The message indicated success stopping : don't call handleStopKeepalive.
|
||||
if (DBG) Log.d(TAG, "Successfully stopped keepalive " + slot + " on " + nai.name());
|
||||
if (KeepaliveInfo.STARTING == ki.mStartedState) {
|
||||
if (SUCCESS == reason) {
|
||||
// Keepalive successfully started.
|
||||
if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
|
||||
ki.mStartedState = KeepaliveInfo.STARTED;
|
||||
try {
|
||||
ki.mCallback.onStarted(slot);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Discarded onStarted(" + slot + ") callback");
|
||||
}
|
||||
} else {
|
||||
// The message indicated some error trying to start or during the course of
|
||||
// keepalive : do call handleStopKeepalive.
|
||||
Log.d(TAG, "Failed to start keepalive " + slot + " on " + nai.name()
|
||||
+ ": " + reason);
|
||||
// The message indicated some error trying to start: do call handleStopKeepalive.
|
||||
handleStopKeepalive(nai, slot, reason);
|
||||
if (DBG) Log.d(TAG, "Keepalive " + slot + " on " + nai.name() + " error " + reason);
|
||||
}
|
||||
} else if (KeepaliveInfo.STOPPING == ki.mStartedState) {
|
||||
// The message indicated result of stopping : don't call handleStopKeepalive.
|
||||
Log.d(TAG, "Stopped keepalive " + slot + " on " + nai.name()
|
||||
+ " stopped: " + reason);
|
||||
ki.mStartedState = KeepaliveInfo.NOT_STARTED;
|
||||
} else {
|
||||
Log.wtf(TAG, "Event " + message.what + "," + slot + "," + reason
|
||||
+ " for keepalive in wrong state: " + ki.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,7 +543,8 @@ public class KeepaliveTracker {
|
||||
try {
|
||||
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
|
||||
KeepaliveInfo.TYPE_NATT, fd);
|
||||
} catch (InvalidSocketException e) {
|
||||
} catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
|
||||
Log.e(TAG, "Fail to construct keepalive", e);
|
||||
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
|
||||
return;
|
||||
}
|
||||
@@ -570,7 +583,8 @@ public class KeepaliveTracker {
|
||||
try {
|
||||
ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
|
||||
KeepaliveInfo.TYPE_TCP, fd);
|
||||
} catch (InvalidSocketException e) {
|
||||
} catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
|
||||
Log.e(TAG, "Fail to construct keepalive e=" + e);
|
||||
notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.connectivity;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.INetd;
|
||||
import android.net.InetAddresses;
|
||||
import android.net.InterfaceConfiguration;
|
||||
@@ -65,6 +66,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
NetworkInfo.State.SUSPENDED,
|
||||
};
|
||||
|
||||
private final IDnsResolver mDnsResolver;
|
||||
private final INetd mNetd;
|
||||
private final INetworkManagementService mNMService;
|
||||
|
||||
@@ -84,7 +86,9 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
private Inet6Address mIPv6Address;
|
||||
private State mState = State.IDLE;
|
||||
|
||||
public Nat464Xlat(NetworkAgentInfo nai, INetd netd, INetworkManagementService nmService) {
|
||||
public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
|
||||
INetworkManagementService nmService) {
|
||||
mDnsResolver = dnsResolver;
|
||||
mNetd = netd;
|
||||
mNMService = nmService;
|
||||
mNetwork = nai;
|
||||
@@ -269,7 +273,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
|
||||
private void startPrefixDiscovery() {
|
||||
try {
|
||||
mNetd.resolverStartPrefix64Discovery(getNetId());
|
||||
mDnsResolver.startPrefix64Discovery(getNetId());
|
||||
mState = State.DISCOVERING;
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
|
||||
@@ -278,7 +282,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
|
||||
private void stopPrefixDiscovery() {
|
||||
try {
|
||||
mNetd.resolverStopPrefix64Discovery(getNetId());
|
||||
mDnsResolver.stopPrefix64Discovery(getNetId());
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.connectivity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.INetd;
|
||||
import android.net.INetworkMonitor;
|
||||
import android.net.LinkProperties;
|
||||
@@ -29,6 +30,7 @@ import android.net.NetworkState;
|
||||
import android.os.Handler;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
@@ -120,7 +122,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
// This Network object is always valid.
|
||||
public final Network network;
|
||||
public LinkProperties linkProperties;
|
||||
// This should only be modified via ConnectivityService.updateCapabilities().
|
||||
// This should only be modified by ConnectivityService, via setNetworkCapabilities().
|
||||
// TODO: make this private with a getter.
|
||||
public NetworkCapabilities networkCapabilities;
|
||||
public final NetworkMisc networkMisc;
|
||||
// Indicates if netd has been told to create this Network. From this point on the appropriate
|
||||
@@ -255,7 +258,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
|
||||
LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
|
||||
NetworkMisc misc, ConnectivityService connService, INetd netd,
|
||||
INetworkManagementService nms, int factorySerialNumber) {
|
||||
IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
|
||||
this.messenger = messenger;
|
||||
asyncChannel = ac;
|
||||
network = net;
|
||||
@@ -263,7 +266,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
linkProperties = lp;
|
||||
networkCapabilities = nc;
|
||||
currentScore = score;
|
||||
clatd = new Nat464Xlat(this, netd, nms);
|
||||
clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
|
||||
mConnService = connService;
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
@@ -278,6 +281,25 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
||||
mNetworkMonitor = networkMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NetworkCapabilities on this NetworkAgentInfo. Also attempts to notify NetworkMonitor
|
||||
* of the new capabilities, if NetworkMonitor has been created.
|
||||
*
|
||||
* <p>If {@link NetworkMonitor#notifyNetworkCapabilitiesChanged(NetworkCapabilities)} fails,
|
||||
* the exception is logged but not reported to callers.
|
||||
*/
|
||||
public void setNetworkCapabilities(NetworkCapabilities nc) {
|
||||
networkCapabilities = nc;
|
||||
final INetworkMonitor nm = mNetworkMonitor;
|
||||
if (nm != null) {
|
||||
try {
|
||||
nm.notifyNetworkCapabilitiesChanged(nc);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error notifying NetworkMonitor of updated NetworkCapabilities", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectivityService connService() {
|
||||
return mConnService;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.connectivity;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
@@ -26,9 +27,12 @@ import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.net.NetworkSpecifier;
|
||||
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;
|
||||
import android.util.Slog;
|
||||
@@ -195,7 +199,20 @@ public class NetworkNotificationManager {
|
||||
title = r.getString(R.string.network_available_sign_in, 0);
|
||||
// TODO: Change this to pull from NetworkInfo once a printable
|
||||
// name has been added to it
|
||||
details = mTelephonyManager.getNetworkOperatorName();
|
||||
NetworkSpecifier specifier = nai.networkCapabilities.getNetworkSpecifier();
|
||||
int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
|
||||
if (specifier instanceof StringNetworkSpecifier) {
|
||||
try {
|
||||
subId = Integer.parseInt(
|
||||
((StringNetworkSpecifier) specifier).specifier);
|
||||
} catch (NumberFormatException e) {
|
||||
Slog.e(TAG, "NumberFormatException on "
|
||||
+ ((StringNetworkSpecifier) specifier).specifier);
|
||||
}
|
||||
}
|
||||
|
||||
details = mTelephonyManager.createForSubscriptionId(subId)
|
||||
.getNetworkOperatorName();
|
||||
break;
|
||||
default:
|
||||
title = r.getString(R.string.network_available_sign_in, 0);
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
|
||||
import static android.Manifest.permission.INTERNET;
|
||||
import static android.Manifest.permission.NETWORK_STACK;
|
||||
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
|
||||
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.os.Process.INVALID_UID;
|
||||
@@ -42,13 +43,15 @@ import android.os.INetworkManagementService;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -83,41 +86,32 @@ public class PermissionMonitor {
|
||||
private final Map<Integer, Boolean> mApps = new HashMap<>();
|
||||
|
||||
private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
|
||||
@Override
|
||||
public void onPackageAdded(String packageName, int uid) {
|
||||
final PackageInfo app = getPackageInfo(packageName);
|
||||
if (app == null) {
|
||||
Slog.wtf(TAG, "Failed to get information of installed package: " + packageName);
|
||||
return;
|
||||
}
|
||||
if (uid == INVALID_UID) {
|
||||
Slog.wtf(TAG, "Failed to get the uid of installed package: " + packageName
|
||||
+ "uid: " + uid);
|
||||
return;
|
||||
}
|
||||
if (app.requestedPermissions == null) {
|
||||
return;
|
||||
}
|
||||
sendPackagePermissionsForUid(uid,
|
||||
getNetdPermissionMask(app.requestedPermissions));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageRemoved(String packageName, int uid) {
|
||||
private int getPermissionForUid(int uid) {
|
||||
int permission = 0;
|
||||
// If there are still packages remain under the same uid, check the permission of the
|
||||
// remaining packages. We only remove the permission for a given uid when all packages
|
||||
// for that uid no longer have that permission.
|
||||
// Check all the packages for this UID. The UID has the permission if any of the
|
||||
// packages in it has the permission.
|
||||
String[] packages = mPackageManager.getPackagesForUid(uid);
|
||||
if (packages != null && packages.length > 0) {
|
||||
for (String name : packages) {
|
||||
final PackageInfo app = getPackageInfo(name);
|
||||
if (app != null && app.requestedPermissions != null) {
|
||||
permission |= getNetdPermissionMask(app.requestedPermissions);
|
||||
permission |= getNetdPermissionMask(app.requestedPermissions,
|
||||
app.requestedPermissionsFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
sendPackagePermissionsForUid(uid, permission);
|
||||
return permission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageAdded(String packageName, int uid) {
|
||||
sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageRemoved(String packageName, int uid) {
|
||||
sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,12 +161,9 @@ public class PermissionMonitor {
|
||||
}
|
||||
|
||||
//TODO: unify the management of the permissions into one codepath.
|
||||
if (app.requestedPermissions != null) {
|
||||
int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions);
|
||||
if (otherNetdPerms != 0) {
|
||||
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
||||
}
|
||||
}
|
||||
int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
|
||||
app.requestedPermissionsFlags);
|
||||
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
||||
}
|
||||
|
||||
List<UserInfo> users = mUserManager.getUsers(true); // exclude dying users
|
||||
@@ -182,6 +173,23 @@ public class PermissionMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
final SparseArray<ArraySet<String>> systemPermission =
|
||||
SystemConfig.getInstance().getSystemPermissions();
|
||||
for (int i = 0; i < systemPermission.size(); i++) {
|
||||
ArraySet<String> perms = systemPermission.valueAt(i);
|
||||
int uid = systemPermission.keyAt(i);
|
||||
int netdPermission = 0;
|
||||
// Get the uids of native services that have UPDATE_DEVICE_STATS permission.
|
||||
if (perms != null) {
|
||||
netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
|
||||
? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0;
|
||||
}
|
||||
// For internet permission, the native services have their own selinux domains and
|
||||
// sepolicy will control the socket creation during run time. netd cannot block the
|
||||
// socket creation based on the permission information here.
|
||||
netdPermission |= INetd.PERMISSION_INTERNET;
|
||||
netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
|
||||
}
|
||||
log("Users: " + mUsers.size() + ", Apps: " + mApps.size());
|
||||
update(mUsers, mApps, true);
|
||||
sendPackagePermissionsToNetd(netdPermsUids);
|
||||
@@ -403,13 +411,17 @@ public class PermissionMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static int getNetdPermissionMask(String[] requestedPermissions) {
|
||||
private static int getNetdPermissionMask(String[] requestedPermissions,
|
||||
int[] requestedPermissionsFlags) {
|
||||
int permissions = 0;
|
||||
for (String permissionName : requestedPermissions) {
|
||||
if (permissionName.equals(INTERNET)) {
|
||||
if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
|
||||
for (int i = 0; i < requestedPermissions.length; i++) {
|
||||
if (requestedPermissions[i].equals(INTERNET)
|
||||
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
|
||||
permissions |= INetd.PERMISSION_INTERNET;
|
||||
}
|
||||
if (permissionName.equals(UPDATE_DEVICE_STATS)) {
|
||||
if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
|
||||
&& ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
|
||||
permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,6 @@ public class IpPrefixTest {
|
||||
assertFalse(p.contains(Address("2001:db8:f00::ace:d00e")));
|
||||
assertFalse(p.contains(Address("2001:db8:f00::bad:d00d")));
|
||||
assertFalse(p.contains(Address("2001:4868:4860::8888")));
|
||||
assertFalse(p.contains((InetAddress)null));
|
||||
assertFalse(p.contains(Address("8.8.8.8")));
|
||||
|
||||
p = new IpPrefix("192.0.2.0/23");
|
||||
|
||||
@@ -44,6 +44,8 @@ public class ParcelableTests {
|
||||
assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable())));
|
||||
|
||||
builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
|
||||
// lease will expire in two hours
|
||||
builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000);
|
||||
// groupHint stays null this time around
|
||||
builder.setDnsAddresses(Collections.emptyList());
|
||||
builder.setMtu(18);
|
||||
@@ -51,6 +53,7 @@ public class ParcelableTests {
|
||||
assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable())));
|
||||
|
||||
builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("6.7.8.9"));
|
||||
builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 3_600_000);
|
||||
builder.setGroupHint("groupHint");
|
||||
builder.setDnsAddresses(Arrays.asList(
|
||||
InetAddress.getByName("ACA1:652B:0911:DE8F:1200:115E:913B:AA2A"),
|
||||
@@ -66,7 +69,7 @@ public class ParcelableTests {
|
||||
// Verify that this test does not miss any new field added later.
|
||||
// If any field is added to NetworkAttributes it must be tested here for parceling
|
||||
// roundtrip.
|
||||
assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
|
||||
assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
|
||||
.filter(f -> !Modifier.isStatic(f.getModifiers())).count());
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ import android.net.ConnectivityManager.PacketKeepalive;
|
||||
import android.net.ConnectivityManager.PacketKeepaliveCallback;
|
||||
import android.net.ConnectivityManager.TooManyRequestsException;
|
||||
import android.net.ConnectivityThread;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.INetd;
|
||||
import android.net.INetworkMonitor;
|
||||
import android.net.INetworkMonitorCallbacks;
|
||||
@@ -212,7 +213,6 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -241,6 +241,7 @@ public class ConnectivityServiceTest {
|
||||
private static final String CLAT_PREFIX = "v4-";
|
||||
private static final String MOBILE_IFNAME = "test_rmnet_data0";
|
||||
private static final String WIFI_IFNAME = "test_wlan0";
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
private MockContext mServiceContext;
|
||||
private WrappedConnectivityService mService;
|
||||
@@ -257,6 +258,7 @@ public class ConnectivityServiceTest {
|
||||
@Mock INetworkManagementService mNetworkManagementService;
|
||||
@Mock INetworkStatsService mStatsService;
|
||||
@Mock INetworkPolicyManager mNpm;
|
||||
@Mock IDnsResolver mMockDnsResolver;
|
||||
@Mock INetd mMockNetd;
|
||||
@Mock NetworkStackClient mNetworkStack;
|
||||
|
||||
@@ -497,9 +499,8 @@ public class ConnectivityServiceTest {
|
||||
};
|
||||
|
||||
try {
|
||||
doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected();
|
||||
doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any());
|
||||
doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
|
||||
doAnswer(validateAnswer).when(mNetworkMonitor).setAcceptPartialConnectivity();
|
||||
} catch (RemoteException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
@@ -1055,8 +1056,8 @@ public class ConnectivityServiceTest {
|
||||
|
||||
public WrappedConnectivityService(Context context, INetworkManagementService netManager,
|
||||
INetworkStatsService statsService, INetworkPolicyManager policyManager,
|
||||
IpConnectivityLog log, INetd netd) {
|
||||
super(context, netManager, statsService, policyManager, log);
|
||||
IpConnectivityLog log, INetd netd, IDnsResolver dnsResolver) {
|
||||
super(context, netManager, statsService, policyManager, dnsResolver, log);
|
||||
mNetd = netd;
|
||||
mLingerDelayMs = TEST_LINGER_DELAY_MS;
|
||||
}
|
||||
@@ -1220,7 +1221,8 @@ public class ConnectivityServiceTest {
|
||||
mStatsService,
|
||||
mNpm,
|
||||
mock(IpConnectivityLog.class),
|
||||
mMockNetd);
|
||||
mMockNetd,
|
||||
mMockDnsResolver);
|
||||
|
||||
final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
|
||||
ArgumentCaptor.forClass(INetworkPolicyListener.class);
|
||||
@@ -2554,8 +2556,7 @@ public class ConnectivityServiceTest {
|
||||
verifyActiveNetwork(TRANSPORT_CELLULAR);
|
||||
}
|
||||
|
||||
// TODO(b/128426024): deflake and re-enable
|
||||
// @Test
|
||||
@Test
|
||||
public void testPartialConnectivity() {
|
||||
// Register network callback.
|
||||
NetworkRequest request = new NetworkRequest.Builder()
|
||||
@@ -2579,20 +2580,24 @@ public class ConnectivityServiceTest {
|
||||
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||
callback.assertNoCallback();
|
||||
|
||||
// With HTTPS probe disabled, NetworkMonitor should pass the network validation with http
|
||||
// probe.
|
||||
mWiFiNetworkAgent.setNetworkValid();
|
||||
// If the user chooses yes to use this partial connectivity wifi, switch the default
|
||||
// network to wifi and check if wifi becomes valid or not.
|
||||
mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
|
||||
false /* always */);
|
||||
// With https probe disabled, NetworkMonitor should pass the network validation with http
|
||||
// probe.
|
||||
mWiFiNetworkAgent.setNetworkValid();
|
||||
// If user accepts partial connectivity network,
|
||||
// NetworkMonitor#setAcceptPartialConnectivity() should be called too.
|
||||
waitForIdle();
|
||||
try {
|
||||
verify(mWiFiNetworkAgent.mNetworkMonitor,
|
||||
timeout(TIMEOUT_MS).times(1)).setAcceptPartialConnectivity();
|
||||
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
|
||||
} catch (RemoteException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
// Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
|
||||
// validated.
|
||||
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
|
||||
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
|
||||
NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED,
|
||||
mWiFiNetworkAgent);
|
||||
@@ -2622,6 +2627,15 @@ public class ConnectivityServiceTest {
|
||||
// acceptUnvalidated is also used as setting for accepting partial networks.
|
||||
mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */);
|
||||
mWiFiNetworkAgent.connect(true);
|
||||
// If user accepted partial connectivity network before,
|
||||
// NetworkMonitor#setAcceptPartialConnectivity() will be called in
|
||||
// ConnectivityService#updateNetworkInfo().
|
||||
waitForIdle();
|
||||
try {
|
||||
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
|
||||
} catch (RemoteException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
|
||||
nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
|
||||
@@ -2636,23 +2650,33 @@ public class ConnectivityServiceTest {
|
||||
// NET_CAPABILITY_PARTIAL_CONNECTIVITY.
|
||||
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||
mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */);
|
||||
// Current design cannot send multi-testResult from NetworkMonitor to ConnectivityService.
|
||||
// So, if user accepts partial connectivity, NetworkMonitor will send PARTIAL_CONNECTIVITY
|
||||
// to ConnectivityService first then send VALID. Once NetworkMonitor support
|
||||
// multi-testResult, this test case also need to be changed to meet the new design.
|
||||
mWiFiNetworkAgent.connectWithPartialConnectivity();
|
||||
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||
// TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
|
||||
// NetworkMonitor detects partial connectivity
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||
mWiFiNetworkAgent.setNetworkValid();
|
||||
// If user accepted partial connectivity network before,
|
||||
// NetworkMonitor#setAcceptPartialConnectivity() will be called in
|
||||
// ConnectivityService#updateNetworkInfo().
|
||||
waitForIdle();
|
||||
try {
|
||||
verify(mWiFiNetworkAgent.mNetworkMonitor,
|
||||
timeout(TIMEOUT_MS).times(1)).setAcceptPartialConnectivity();
|
||||
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
|
||||
} catch (RemoteException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||
callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
|
||||
callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
|
||||
// Wifi should be the default network.
|
||||
// TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
|
||||
// NetworkMonitor detects partial connectivity
|
||||
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||
callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
|
||||
mWiFiNetworkAgent.setNetworkValid();
|
||||
// Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
|
||||
// validated.
|
||||
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
|
||||
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
|
||||
mWiFiNetworkAgent.disconnect();
|
||||
callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -3022,6 +3046,47 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidSignalStrength() {
|
||||
NetworkRequest r = new NetworkRequest.Builder()
|
||||
.addCapability(NET_CAPABILITY_INTERNET)
|
||||
.addTransportType(TRANSPORT_WIFI)
|
||||
.setSignalStrength(-75)
|
||||
.build();
|
||||
// Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP
|
||||
// permission should get SecurityException.
|
||||
try {
|
||||
mCm.registerNetworkCallback(r, new NetworkCallback());
|
||||
fail("Expected SecurityException filing a callback with signal strength");
|
||||
} catch (SecurityException expected) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
mCm.registerNetworkCallback(r, PendingIntent.getService(
|
||||
mServiceContext, 0, new Intent(), 0));
|
||||
fail("Expected SecurityException filing a callback with signal strength");
|
||||
} catch (SecurityException expected) {
|
||||
// expected
|
||||
}
|
||||
|
||||
// Requesting a Network with signal strength should get IllegalArgumentException.
|
||||
try {
|
||||
mCm.requestNetwork(r, new NetworkCallback());
|
||||
fail("Expected IllegalArgumentException filing a request with signal strength");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
mCm.requestNetwork(r, PendingIntent.getService(
|
||||
mServiceContext, 0, new Intent(), 0));
|
||||
fail("Expected IllegalArgumentException filing a request with signal strength");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegisterDefaultNetworkCallback() throws Exception {
|
||||
final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
|
||||
@@ -4022,8 +4087,13 @@ public class ConnectivityServiceTest {
|
||||
callback3.expectStopped();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface ThrowingConsumer<T> {
|
||||
void accept(T t) throws Exception;
|
||||
}
|
||||
|
||||
// Helper method to prepare the executor and run test
|
||||
private void runTestWithSerialExecutors(Consumer<Executor> functor) {
|
||||
private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) throws Exception {
|
||||
final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
|
||||
final Executor executorInline = (Runnable r) -> r.run();
|
||||
functor.accept(executorSingleThread);
|
||||
@@ -4032,23 +4102,15 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNattSocketKeepalives() {
|
||||
runTestWithSerialExecutors(executor -> {
|
||||
try {
|
||||
doTestNattSocketKeepalivesWithExecutor(executor);
|
||||
doTestNattSocketKeepalivesFdWithExecutor(executor);
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
});
|
||||
public void testNattSocketKeepalives() throws Exception {
|
||||
runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor));
|
||||
runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor));
|
||||
}
|
||||
|
||||
private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception {
|
||||
// TODO: 1. Move this outside of ConnectivityServiceTest.
|
||||
// 2. Make test to verify that Nat-T keepalive socket is created by IpSecService.
|
||||
// 3. Mock ipsec service.
|
||||
// 4. Find a free port instead of a fixed port.
|
||||
final int srcPort = 12345;
|
||||
final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
|
||||
final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
|
||||
final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
|
||||
@@ -4059,7 +4121,8 @@ public class ConnectivityServiceTest {
|
||||
final int invalidKaInterval = 9;
|
||||
|
||||
final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
|
||||
final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(srcPort);
|
||||
final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket();
|
||||
final int srcPort = testSocket.getPort();
|
||||
|
||||
LinkProperties lp = new LinkProperties();
|
||||
lp.setInterfaceName("wlan12");
|
||||
@@ -4179,6 +4242,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Check that keepalive slots start from 1 and increment. The first one gets slot 1.
|
||||
mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
|
||||
int srcPort2 = 0;
|
||||
try (SocketKeepalive ka = mCm.createSocketKeepalive(
|
||||
myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
|
||||
ka.start(validKaInterval);
|
||||
@@ -4186,7 +4250,8 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// The second one gets slot 2.
|
||||
mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
|
||||
final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(6789);
|
||||
final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket();
|
||||
srcPort2 = testSocket2.getPort();
|
||||
TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor);
|
||||
try (SocketKeepalive ka2 = mCm.createSocketKeepalive(
|
||||
myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) {
|
||||
@@ -4204,20 +4269,18 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
}
|
||||
|
||||
// Check that there is no port leaked after all keepalives and sockets are closed.
|
||||
assertFalse(isUdpPortInUse(srcPort));
|
||||
assertFalse(isUdpPortInUse(srcPort2));
|
||||
|
||||
mWiFiNetworkAgent.disconnect();
|
||||
waitFor(mWiFiNetworkAgent.getDisconnectedCV());
|
||||
mWiFiNetworkAgent = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpSocketKeepalives() {
|
||||
runTestWithSerialExecutors(executor -> {
|
||||
try {
|
||||
doTestTcpSocketKeepalivesWithExecutor(executor);
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
});
|
||||
public void testTcpSocketKeepalives() throws Exception {
|
||||
runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor));
|
||||
}
|
||||
|
||||
private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception {
|
||||
@@ -4292,7 +4355,6 @@ public class ConnectivityServiceTest {
|
||||
}
|
||||
|
||||
private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception {
|
||||
final int srcPort = 12345;
|
||||
final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
|
||||
final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0");
|
||||
final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
|
||||
@@ -4311,7 +4373,8 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Prepare the target file descriptor, keep only one instance.
|
||||
final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
|
||||
final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(srcPort);
|
||||
final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket();
|
||||
final int srcPort = testSocket.getPort();
|
||||
final ParcelFileDescriptor testPfd =
|
||||
ParcelFileDescriptor.dup(testSocket.getFileDescriptor());
|
||||
testSocket.close();
|
||||
@@ -4759,14 +4822,14 @@ public class ConnectivityServiceTest {
|
||||
ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
|
||||
|
||||
// Clear any interactions that occur as a result of CS starting up.
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
waitForIdle();
|
||||
verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork(
|
||||
anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
|
||||
verifyNoMoreInteractions(mNetworkManagementService);
|
||||
verify(mMockDnsResolver, never()).setResolverConfiguration(
|
||||
anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
|
||||
eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
|
||||
final LinkProperties cellLp = new LinkProperties();
|
||||
cellLp.setInterfaceName(MOBILE_IFNAME);
|
||||
@@ -4783,28 +4846,29 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.connect(false);
|
||||
waitForIdle();
|
||||
// CS tells netd about the empty DNS config for this network.
|
||||
verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
|
||||
anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
|
||||
reset(mNetworkManagementService);
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
|
||||
eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
cellLp.addDnsServer(InetAddress.getByName("2001:db8::1"));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
waitForIdle();
|
||||
verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
anyInt(), mStringArrayCaptor.capture(), any(), any(),
|
||||
eq(""), tlsServers.capture());
|
||||
eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
|
||||
assertEquals(1, mStringArrayCaptor.getValue().length);
|
||||
assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "2001:db8::1"));
|
||||
// Opportunistic mode.
|
||||
assertTrue(ArrayUtils.contains(tlsServers.getValue(), "2001:db8::1"));
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
cellLp.addDnsServer(InetAddress.getByName("192.0.2.1"));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
waitForIdle();
|
||||
verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
anyInt(), mStringArrayCaptor.capture(), any(), any(),
|
||||
eq(""), tlsServers.capture());
|
||||
eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
|
||||
assertEquals(2, mStringArrayCaptor.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
@@ -4812,7 +4876,7 @@ public class ConnectivityServiceTest {
|
||||
assertEquals(2, tlsServers.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
final String TLS_SPECIFIER = "tls.example.com";
|
||||
final String TLS_SERVER6 = "2001:db8:53::53";
|
||||
@@ -4822,22 +4886,21 @@ public class ConnectivityServiceTest {
|
||||
new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel());
|
||||
|
||||
waitForIdle();
|
||||
verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
anyInt(), mStringArrayCaptor.capture(), any(), any(),
|
||||
eq(TLS_SPECIFIER), eq(TLS_SERVERS));
|
||||
eq(TLS_SPECIFIER), eq(TLS_SERVERS), eq(EMPTY_STRING_ARRAY));
|
||||
assertEquals(2, mStringArrayCaptor.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateDnsSettingsChange() throws Exception {
|
||||
final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
|
||||
|
||||
// Clear any interactions that occur as a result of CS starting up.
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
// The default on Android is opportunistic mode ("Automatic").
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
|
||||
@@ -4850,9 +4913,10 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
|
||||
waitForIdle();
|
||||
// CS tells netd about the empty DNS config for this network.
|
||||
verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork(
|
||||
anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
|
||||
verifyNoMoreInteractions(mNetworkManagementService);
|
||||
verify(mMockDnsResolver, never()).setResolverConfiguration(
|
||||
anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
|
||||
eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
|
||||
final LinkProperties cellLp = new LinkProperties();
|
||||
cellLp.setInterfaceName(MOBILE_IFNAME);
|
||||
@@ -4871,9 +4935,9 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
mCellNetworkAgent.connect(false);
|
||||
waitForIdle();
|
||||
verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
anyInt(), mStringArrayCaptor.capture(), any(), any(),
|
||||
eq(""), tlsServers.capture());
|
||||
eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
|
||||
assertEquals(2, mStringArrayCaptor.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
@@ -4881,7 +4945,7 @@ public class ConnectivityServiceTest {
|
||||
assertEquals(2, tlsServers.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
|
||||
cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
|
||||
mCellNetworkAgent);
|
||||
@@ -4893,26 +4957,26 @@ public class ConnectivityServiceTest {
|
||||
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
|
||||
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
|
||||
verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork(
|
||||
verify(mMockDnsResolver, times(1)).setResolverConfiguration(
|
||||
anyInt(), mStringArrayCaptor.capture(), any(), any(),
|
||||
eq(""), eq(EMPTY_STRING_ARRAY));
|
||||
eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
|
||||
assertEquals(2, mStringArrayCaptor.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
|
||||
verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
anyInt(), mStringArrayCaptor.capture(), any(), any(),
|
||||
eq(""), tlsServers.capture());
|
||||
eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
|
||||
assertEquals(2, mStringArrayCaptor.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
assertEquals(2, tlsServers.getValue().length);
|
||||
assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
|
||||
new String[]{"2001:db8::1", "192.0.2.1"}));
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
cellNetworkCallback.assertNoCallback();
|
||||
|
||||
setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
|
||||
@@ -5743,6 +5807,7 @@ public class ConnectivityServiceTest {
|
||||
cellLp.addRoute(new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME));
|
||||
cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME));
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockDnsResolver);
|
||||
when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
|
||||
.thenReturn(getClatInterfaceConfig(myIpv4));
|
||||
|
||||
@@ -5750,7 +5815,7 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
mCellNetworkAgent.connect(true);
|
||||
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
|
||||
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
|
||||
|
||||
// Switching default network updates TCP buffer sizes.
|
||||
verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES);
|
||||
@@ -5760,17 +5825,22 @@ public class ConnectivityServiceTest {
|
||||
cellLp.addLinkAddress(myIpv4);
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
|
||||
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
|
||||
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
|
||||
eq(cellNetId), eq(EMPTY_STRING_ARRAY), any(), any(),
|
||||
eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
|
||||
|
||||
verifyNoMoreInteractions(mMockNetd);
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
reset(mMockNetd);
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
// Remove IPv4 address. Expect prefix discovery to be started again.
|
||||
cellLp.removeLinkAddress(myIpv4);
|
||||
cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
|
||||
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
|
||||
|
||||
// When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
|
||||
Nat464Xlat clat = mService.getNat464Xlat(mCellNetworkAgent);
|
||||
@@ -5800,6 +5870,12 @@ public class ConnectivityServiceTest {
|
||||
assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST);
|
||||
assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0));
|
||||
|
||||
verify(mMockDnsResolver, times(1)).setResolverConfiguration(
|
||||
eq(cellNetId), mStringArrayCaptor.capture(), any(), any(),
|
||||
eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
|
||||
assertEquals(1, mStringArrayCaptor.getValue().length);
|
||||
assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "8.8.8.8"));
|
||||
|
||||
// Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
|
||||
// linkproperties are cleaned up.
|
||||
cellLp.addLinkAddress(myIpv4);
|
||||
@@ -5807,7 +5883,7 @@ public class ConnectivityServiceTest {
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
|
||||
verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
|
||||
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
|
||||
|
||||
// As soon as stop is called, the linkproperties lose the stacked interface.
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
@@ -5822,7 +5898,9 @@ public class ConnectivityServiceTest {
|
||||
networkCallback.assertNoCallback();
|
||||
|
||||
verifyNoMoreInteractions(mMockNetd);
|
||||
verifyNoMoreInteractions(mMockDnsResolver);
|
||||
reset(mMockNetd);
|
||||
reset(mMockDnsResolver);
|
||||
|
||||
// Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
|
||||
@@ -5836,7 +5914,7 @@ public class ConnectivityServiceTest {
|
||||
cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
|
||||
mCellNetworkAgent.sendLinkProperties(cellLp);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
|
||||
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
|
||||
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
|
||||
kNat64PrefixString, 96);
|
||||
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
|
||||
@@ -5919,6 +5997,7 @@ public class ConnectivityServiceTest {
|
||||
|
||||
// Disconnect cell
|
||||
reset(mNetworkManagementService);
|
||||
reset(mMockNetd);
|
||||
mCellNetworkAgent.disconnect();
|
||||
networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
|
||||
// LOST callback is triggered earlier than removing idle timer. Broadcast should also be
|
||||
@@ -5926,8 +6005,9 @@ public class ConnectivityServiceTest {
|
||||
// unexpectedly before network being removed.
|
||||
waitForIdle();
|
||||
verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
|
||||
verify(mNetworkManagementService, times(1)).removeNetwork(
|
||||
eq(mCellNetworkAgent.getNetwork().netId));
|
||||
verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
|
||||
verify(mMockDnsResolver, times(1))
|
||||
.clearResolverConfiguration(eq(mCellNetworkAgent.getNetwork().netId));
|
||||
|
||||
// Disconnect wifi
|
||||
ConditionVariable cv = waitForConnectivityBroadcasts(1);
|
||||
|
||||
@@ -29,13 +29,13 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.IpPrefix;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.shared.PrivateDnsConfig;
|
||||
import android.os.INetworkManagementService;
|
||||
import android.provider.Settings;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
@@ -73,7 +73,7 @@ public class DnsManagerTest {
|
||||
MockContentResolver mContentResolver;
|
||||
|
||||
@Mock Context mCtx;
|
||||
@Mock INetworkManagementService mNMService;
|
||||
@Mock IDnsResolver mMockDnsResolver;
|
||||
@Mock MockableSystemProperties mSystemProperties;
|
||||
|
||||
@Before
|
||||
@@ -83,7 +83,7 @@ public class DnsManagerTest {
|
||||
mContentResolver.addProvider(Settings.AUTHORITY,
|
||||
new FakeSettingsProvider());
|
||||
when(mCtx.getContentResolver()).thenReturn(mContentResolver);
|
||||
mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties);
|
||||
mDnsManager = new DnsManager(mCtx, mMockDnsResolver, mSystemProperties);
|
||||
|
||||
// Clear the private DNS settings
|
||||
Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.INetd;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
@@ -69,6 +70,7 @@ public class LingerMonitorTest {
|
||||
LingerMonitor mMonitor;
|
||||
|
||||
@Mock ConnectivityService mConnService;
|
||||
@Mock IDnsResolver mDnsResolver;
|
||||
@Mock INetd mNetd;
|
||||
@Mock INetworkManagementService mNMS;
|
||||
@Mock Context mCtx;
|
||||
@@ -353,7 +355,7 @@ public class LingerMonitorTest {
|
||||
caps.addCapability(0);
|
||||
caps.addTransportType(transport);
|
||||
NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
|
||||
caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS,
|
||||
caps, 50, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS,
|
||||
NetworkFactory.SerialNumber.NONE);
|
||||
nai.everValidated = true;
|
||||
return nai;
|
||||
|
||||
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IDnsResolver;
|
||||
import android.net.INetd;
|
||||
import android.net.InterfaceConfiguration;
|
||||
import android.net.IpPrefix;
|
||||
@@ -63,6 +64,7 @@ public class Nat464XlatTest {
|
||||
|
||||
@Mock ConnectivityService mConnectivity;
|
||||
@Mock NetworkMisc mMisc;
|
||||
@Mock IDnsResolver mDnsResolver;
|
||||
@Mock INetd mNetd;
|
||||
@Mock INetworkManagementService mNms;
|
||||
@Mock InterfaceConfiguration mConfig;
|
||||
@@ -72,7 +74,7 @@ public class Nat464XlatTest {
|
||||
Handler mHandler;
|
||||
|
||||
Nat464Xlat makeNat464Xlat() {
|
||||
return new Nat464Xlat(mNai, mNetd, mNms) {
|
||||
return new Nat464Xlat(mNai, mNetd, mDnsResolver, mNms) {
|
||||
@Override protected int getNetId() {
|
||||
return NETID;
|
||||
}
|
||||
@@ -205,7 +207,7 @@ public class Nat464XlatTest {
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
assertTrue(c.getValue().getStackedLinks().isEmpty());
|
||||
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
|
||||
assertIdle(nat);
|
||||
|
||||
// Stacked interface removed notification arrives and is ignored.
|
||||
@@ -331,7 +333,7 @@ public class Nat464XlatTest {
|
||||
verify(mNetd).clatdStop(eq(BASE_IFACE));
|
||||
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
|
||||
assertTrue(c.getValue().getStackedLinks().isEmpty());
|
||||
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
|
||||
assertIdle(nat);
|
||||
@@ -358,7 +360,7 @@ public class Nat464XlatTest {
|
||||
|
||||
verify(mNetd).clatdStop(eq(BASE_IFACE));
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
|
||||
assertIdle(nat);
|
||||
|
||||
// In-flight interface up notification arrives: no-op
|
||||
@@ -390,7 +392,7 @@ public class Nat464XlatTest {
|
||||
|
||||
verify(mNetd).clatdStop(eq(BASE_IFACE));
|
||||
verify(mNms).unregisterObserver(eq(nat));
|
||||
verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
|
||||
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
|
||||
assertIdle(nat);
|
||||
|
||||
verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
|
||||
|
||||
@@ -57,6 +57,7 @@ public class NetworkAttributesTest {
|
||||
final NetworkAttributes na =
|
||||
new NetworkAttributes(
|
||||
(Inet4Address) Inet4Address.getByAddress(new byte[] {1, 2, 3, 4}),
|
||||
System.currentTimeMillis() + 7_200_000,
|
||||
"some hint",
|
||||
Arrays.asList(Inet4Address.getByAddress(new byte[] {5, 6, 7, 8}),
|
||||
Inet4Address.getByAddress(new byte[] {9, 0, 1, 2})),
|
||||
|
||||
Reference in New Issue
Block a user