Merge changes from topic "cts-networkprovider"
* changes:
Add cts test for NetworkProvider
Adjust permission of NetworkProvider related API
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6b13a17..b288af8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2727,7 +2727,9 @@
break;
}
case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
- handleUpdateLinkProperties(nai, (LinkProperties) msg.obj);
+ LinkProperties newLp = (LinkProperties) msg.obj;
+ processLinkPropertiesFromAgent(nai, newLp);
+ handleUpdateLinkProperties(nai, newLp);
break;
}
case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
@@ -5826,7 +5828,7 @@
}
LinkProperties lp = new LinkProperties(linkProperties);
- lp.ensureDirectlyConnectedRoutes();
+
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
@@ -5834,8 +5836,11 @@
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
this, mNetd, mDnsResolver, mNMS, providerId);
- // Make sure the network capabilities reflect what the agent info says.
+
+ // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
+ processLinkPropertiesFromAgent(nai, nai.linkProperties);
+
final String extraInfo = networkInfo.getExtraInfo();
final String name = TextUtils.isEmpty(extraInfo)
? nai.networkCapabilities.getSsid() : extraInfo;
@@ -5873,6 +5878,10 @@
updateUids(nai, null, nai.networkCapabilities);
}
+ private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
+ lp.ensureDirectlyConnectedRoutes();
+ }
+
private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
@NonNull LinkProperties oldLp) {
int netId = networkAgent.network.netId;
@@ -6400,13 +6409,13 @@
// Ignore updates for disconnected networks
return;
}
- // newLp is already a defensive copy.
- newLp.ensureDirectlyConnectedRoutes();
if (VDBG || DDBG) {
log("Update of LinkProperties for " + nai.toShortString()
+ "; created=" + nai.created
+ "; everConnected=" + nai.everConnected);
}
+ // TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
+ // modify its oldLp parameter.
updateLinkProperties(nai, newLp, new LinkProperties(nai.linkProperties));
}
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 741cb5b..e6b2d26 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -81,6 +81,9 @@
RUNNING, // start() called, and the stacked iface is known to be up.
}
+ /** NAT64 prefix currently in use. Only valid in STARTING or RUNNING states. */
+ private IpPrefix mNat64PrefixInUse;
+ /** NAT64 prefix (if any) discovered from DNS via RFC 7050. */
private IpPrefix mNat64PrefixFromDns;
private String mBaseIface;
private String mIface;
@@ -178,9 +181,10 @@
return;
}
+ mNat64PrefixInUse = getNat64Prefix();
String addrStr = null;
try {
- addrStr = mNetd.clatdStart(baseIface, getNat64Prefix().toString());
+ addrStr = mNetd.clatdStart(baseIface, mNat64PrefixInUse.toString());
} catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error starting clatd on " + baseIface + ": " + e);
}
@@ -211,12 +215,13 @@
} catch (RemoteException | IllegalStateException e) {
Slog.e(TAG, "Error unregistering clatd observer on " + mBaseIface + ": " + e);
}
+ mNat64PrefixInUse = null;
mIface = null;
mBaseIface = null;
if (requiresClat(mNetwork)) {
mState = State.DISCOVERING;
} else {
- stopPrefixDiscovery();
+ stopPrefixDiscovery(); // Enters IDLE state.
}
}
@@ -274,19 +279,32 @@
private void startPrefixDiscovery() {
try {
mDnsResolver.startPrefix64Discovery(getNetId());
- mState = State.DISCOVERING;
} catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
}
+ mState = State.DISCOVERING;
}
private void stopPrefixDiscovery() {
try {
mDnsResolver.stopPrefix64Discovery(getNetId());
- mState = State.IDLE;
} catch (RemoteException | ServiceSpecificException e) {
Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
}
+ mState = State.IDLE;
+ }
+
+ private void maybeHandleNat64PrefixChange() {
+ final IpPrefix newPrefix = getNat64Prefix();
+ if (!Objects.equals(mNat64PrefixInUse, newPrefix)) {
+ Slog.d(TAG, "NAT64 prefix changed from " + mNat64PrefixInUse + " to "
+ + newPrefix);
+ stop();
+ // It's safe to call update here, even though this method is called from update, because
+ // stop() is guaranteed to have moved out of STARTING and RUNNING, which are the only
+ // states in which this method can be called.
+ update();
+ }
}
/**
@@ -325,11 +343,11 @@
// Stop clatd and go back into DISCOVERING or idle.
if (!shouldStartClat(mNetwork)) {
stop();
+ break;
}
+ // Only necessary while clat is actually started.
+ maybeHandleNat64PrefixChange();
break;
- // TODO: support the NAT64 prefix changing after it's been discovered. There is
- // no need to support this at the moment because it cannot happen without
- // changes to the Dns64Configuration code in netd.
}
}
@@ -347,6 +365,8 @@
* has no idea that 464xlat is running on top of it.
*/
public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) {
+ // This must be done even if clatd is not running, because otherwise shouldStartClat would
+ // never return true.
lp.setNat64Prefix(getNat64Prefix());
if (!isRunning()) {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index b864e37..dad0363 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -5969,6 +5969,9 @@
final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64");
final String kNat64PrefixString = "2001:db8:64:64:64:64::";
final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96);
+ final String kOtherNat64PrefixString = "64:ff9b::";
+ final IpPrefix kOtherNat64Prefix = new IpPrefix(
+ InetAddress.getByName(kOtherNat64PrefixString), 96);
final RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, myIpv6.getAddress(),
MOBILE_IFNAME);
final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME);
@@ -6082,6 +6085,24 @@
}
reset(mMockNetd);
+ // Change the NAT64 prefix without first removing it.
+ // Expect clatd to be stopped and started with the new prefix.
+ mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
+ kOtherNat64PrefixString, 96);
+ networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+ (lp) -> lp.getStackedLinks().size() == 0);
+ verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
+ assertRoutesRemoved(cellNetId, stackedDefault);
+
+ verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kOtherNat64Prefix.toString());
+ networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+ (lp) -> lp.getNat64Prefix().equals(kOtherNat64Prefix));
+ clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
+ networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+ (lp) -> lp.getStackedLinks().size() == 1);
+ assertRoutesAdded(cellNetId, stackedDefault);
+ reset(mMockNetd);
+
// Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
// linkproperties are cleaned up.
cellLp.addLinkAddress(myIpv4);
@@ -6096,7 +6117,7 @@
networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork());
LinkProperties expected = new LinkProperties(cellLp);
- expected.setNat64Prefix(kNat64Prefix);
+ expected.setNat64Prefix(kOtherNat64Prefix);
assertEquals(expected, actualLpAfterIpv4);
assertEquals(0, actualLpAfterIpv4.getStackedLinks().size());
assertRoutesRemoved(cellNetId, stackedDefault);
@@ -6115,7 +6136,7 @@
// Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
- kNat64PrefixString, 96);
+ kOtherNat64PrefixString, 96);
networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
(lp) -> lp.getNat64Prefix() == null);
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index a392ae3..0a603b8 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -18,6 +18,8 @@
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+import static android.net.NetworkCapabilities.MAX_TRANSPORT;
+import static android.net.NetworkCapabilities.MIN_TRANSPORT;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
@@ -30,6 +32,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.reset;
@@ -44,16 +47,19 @@
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.ResolverOptionsParcel;
import android.net.ResolverParamsParcel;
import android.net.RouteInfo;
import android.net.shared.PrivateDnsConfig;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
+import android.util.SparseArray;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.util.MessageUtils;
import com.android.internal.util.test.FakeSettingsProvider;
import org.junit.Before;
@@ -354,4 +360,23 @@
expectedParams.resolverOptions = new ResolverOptionsParcel();
assertResolverParamsEquals(actualParams, expectedParams);
}
+
+ @Test
+ public void testTransportTypesEqual() throws Exception {
+ SparseArray<String> ncTransTypes = MessageUtils.findMessageNames(
+ new Class[] { NetworkCapabilities.class }, new String[]{ "TRANSPORT_" });
+ SparseArray<String> dnsTransTypes = MessageUtils.findMessageNames(
+ new Class[] { IDnsResolver.class }, new String[]{ "TRANSPORT_" });
+ assertEquals(0, MIN_TRANSPORT);
+ assertEquals(MAX_TRANSPORT + 1, ncTransTypes.size());
+ // TRANSPORT_UNKNOWN in IDnsResolver is defined to -1 and only for resolver.
+ assertEquals("TRANSPORT_UNKNOWN", dnsTransTypes.get(-1));
+ assertEquals(ncTransTypes.size(), dnsTransTypes.size() - 1);
+ for (int i = MIN_TRANSPORT; i < MAX_TRANSPORT; i++) {
+ String name = ncTransTypes.get(i, null);
+ assertNotNull("Could not find NetworkCapabilies.TRANSPORT_* constant equal to "
+ + i, name);
+ assertEquals(name, dnsTransTypes.get(i));
+ }
+ }
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 6e63313..1db90b7 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -109,7 +109,7 @@
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
import com.android.testutils.HandlerUtilsKt;
-import com.android.testutils.TestableNetworkStatsProvider;
+import com.android.testutils.TestableNetworkStatsProviderBinder;
import libcore.io.IoUtils;
@@ -1118,7 +1118,8 @@
expectNetworkStatsUidDetail(buildEmptyStats());
// Register custom provider and retrieve callback.
- final TestableNetworkStatsProvider provider = new TestableNetworkStatsProvider();
+ final TestableNetworkStatsProviderBinder provider =
+ new TestableNetworkStatsProviderBinder();
final INetworkStatsProviderCallback cb =
mService.registerNetworkStatsProvider("TEST", provider);
assertNotNull(cb);
@@ -1176,7 +1177,8 @@
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
// Register custom provider and retrieve callback.
- final TestableNetworkStatsProvider provider = new TestableNetworkStatsProvider();
+ final TestableNetworkStatsProviderBinder provider =
+ new TestableNetworkStatsProviderBinder();
final INetworkStatsProviderCallback cb =
mService.registerNetworkStatsProvider("TEST", provider);
assertNotNull(cb);