Snap for 8076125 from 6ee91ee624dbef287f3ef0f2cd6edb3d90101ffb to mainline-wifi-release Change-Id: Ibbc67f7c63d3694ade79e0bfe1e2bbba07708620
diff --git a/Android.bp b/Android.bp index 026870c..dd7e8c6 100644 --- a/Android.bp +++ b/Android.bp
@@ -158,10 +158,10 @@ // stable and have no defined version number. These could be called 10000, but they use the next // integer so if the next SDK release happens to use that integer, we don't need to rename them. java_library { - name: "NetworkStackApi32Shims", + name: "NetworkStackApi33Shims", defaults: ["NetworkStackShimsDefaults"], srcs: [ - "apishim/32/**/*.java", + "apishim/33/**/*.java", ], libs: [ "NetworkStackShimsCommon", @@ -185,12 +185,13 @@ "NetworkStackApi29Shims", "NetworkStackApi30Shims", "NetworkStackApi31Shims", - "NetworkStackApi32Shims", + "NetworkStackApi33Shims", ], sdk_version: "module_current", visibility: [ "//packages/modules/Connectivity/Tethering", "//packages/modules/Connectivity/tests/cts/net", + "//packages/modules/Connectivity/tests/cts/hostside/app", ], } @@ -211,6 +212,7 @@ visibility: [ "//packages/modules/Connectivity/Tethering", "//packages/modules/Connectivity/tests/cts/net", + "//packages/modules/Connectivity/tests/cts/hostside/app", ], }
diff --git a/apishim/29/com/android/networkstack/apishim/api29/VpnServiceBuilderShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/VpnServiceBuilderShimImpl.java new file mode 100644 index 0000000..0f221bf --- /dev/null +++ b/apishim/29/com/android/networkstack/apishim/api29/VpnServiceBuilderShimImpl.java
@@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.networkstack.apishim.api29; + +import android.net.IpPrefix; +import android.net.VpnService; + +import com.android.networkstack.apishim.common.UnsupportedApiLevelException; +import com.android.networkstack.apishim.common.VpnServiceBuilderShim; + +/** + * Implementation of {@link com.android.networkstack.apishim.common.VpnServiceBuilderShim}. + */ +public class VpnServiceBuilderShimImpl implements VpnServiceBuilderShim { + + /** + * Get a new instance of {@link VpnServiceBuilderShim}. + */ + public static VpnServiceBuilderShim newInstance() { + return new VpnServiceBuilderShimImpl(); + } + + @Override + public VpnService.Builder excludeRoute(VpnService.Builder builder, IpPrefix prefix) + throws UnsupportedApiLevelException { + throw new UnsupportedApiLevelException("Only supported after API level 31."); + } + + @Override + public VpnService.Builder addRoute(VpnService.Builder builder, IpPrefix prefix) + throws UnsupportedApiLevelException { + throw new UnsupportedApiLevelException("Only supported after API level 31."); + } +}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/VpnServiceBuilderShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/VpnServiceBuilderShimImpl.java new file mode 100644 index 0000000..8b82935 --- /dev/null +++ b/apishim/31/com/android/networkstack/apishim/api31/VpnServiceBuilderShimImpl.java
@@ -0,0 +1,24 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.networkstack.apishim.api31; + +/** + * Implementation of {@link com.android.networkstack.apishim.common.VpnServiceBuilderShim}. + */ +public class VpnServiceBuilderShimImpl extends + com.android.networkstack.apishim.api29.VpnServiceBuilderShimImpl { +}
diff --git a/apishim/32/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java b/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java similarity index 92% rename from apishim/32/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java rename to apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java index 2056b1b..63fa021 100644 --- a/apishim/32/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java +++ b/apishim/33/com/android/networkstack/apishim/CaptivePortalDataShimImpl.java
@@ -27,7 +27,7 @@ /** * Compatibility implementation of {@link CaptivePortalDataShim}. */ -@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods +@RequiresApi(Build.VERSION_CODES.TIRAMISU) public class CaptivePortalDataShimImpl extends com.android.networkstack.apishim.api31.CaptivePortalDataShimImpl { // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java similarity index 92% rename from apishim/32/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java rename to apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java index a7aa0c8..7675960 100644 --- a/apishim/32/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java +++ b/apishim/33/com/android/networkstack/apishim/ConnectivityManagerShimImpl.java
@@ -26,7 +26,7 @@ /** * Compatibility implementation of {@link ConnectivityManagerShim}. */ -@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods +@RequiresApi(Build.VERSION_CODES.TIRAMISU) public class ConnectivityManagerShimImpl extends com.android.networkstack.apishim.api31.ConnectivityManagerShimImpl { // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/ConstantsShim.java b/apishim/33/com/android/networkstack/apishim/ConstantsShim.java similarity index 96% rename from apishim/32/com/android/networkstack/apishim/ConstantsShim.java rename to apishim/33/com/android/networkstack/apishim/ConstantsShim.java index 0a5b555..6d146f5 100644 --- a/apishim/32/com/android/networkstack/apishim/ConstantsShim.java +++ b/apishim/33/com/android/networkstack/apishim/ConstantsShim.java
@@ -29,5 +29,5 @@ * the shimmed objects and methods themselves. */ @VisibleForTesting - public static final int VERSION = 32; + public static final int VERSION = 33; }
diff --git a/apishim/32/com/android/networkstack/apishim/NetworkInformationShimImpl.java b/apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java similarity index 91% rename from apishim/32/com/android/networkstack/apishim/NetworkInformationShimImpl.java rename to apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java index 28aa75c..d51ef40 100644 --- a/apishim/32/com/android/networkstack/apishim/NetworkInformationShimImpl.java +++ b/apishim/33/com/android/networkstack/apishim/NetworkInformationShimImpl.java
@@ -25,7 +25,7 @@ /** * Compatibility implementation of {@link NetworkInformationShim}. */ -@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods +@RequiresApi(Build.VERSION_CODES.TIRAMISU) public class NetworkInformationShimImpl extends com.android.networkstack.apishim.api31.NetworkInformationShimImpl { // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/NetworkRequestShimImpl.java b/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java similarity index 86% rename from apishim/32/com/android/networkstack/apishim/NetworkRequestShimImpl.java rename to apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java index 95ae5ba..72dfef2 100644 --- a/apishim/32/com/android/networkstack/apishim/NetworkRequestShimImpl.java +++ b/apishim/33/com/android/networkstack/apishim/NetworkRequestShimImpl.java
@@ -23,9 +23,9 @@ import com.android.networkstack.apishim.common.NetworkRequestShim; /** - * Implementation of {@link NetworkRequestShim} for API 31. + * Implementation of {@link NetworkRequestShim} for API 33. */ -@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods +@RequiresApi(Build.VERSION_CODES.TIRAMISU) public class NetworkRequestShimImpl extends com.android.networkstack.apishim.api31.NetworkRequestShimImpl { // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/NetworkShimImpl.java b/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java similarity index 91% rename from apishim/32/com/android/networkstack/apishim/NetworkShimImpl.java rename to apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java index 2e31a78..0968c4c 100644 --- a/apishim/32/com/android/networkstack/apishim/NetworkShimImpl.java +++ b/apishim/33/com/android/networkstack/apishim/NetworkShimImpl.java
@@ -25,7 +25,7 @@ /** * Compatibility implementation of {@link com.android.networkstack.apishim.common.NetworkShim}. */ -@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods +@RequiresApi(Build.VERSION_CODES.TIRAMISU) public class NetworkShimImpl extends com.android.networkstack.apishim.api30.NetworkShimImpl { // Currently, this is the same as the API 31 shim, so inherit everything from that. protected NetworkShimImpl(@NonNull Network network) {
diff --git a/apishim/32/com/android/networkstack/apishim/SettingsShimImpl.java b/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java similarity index 90% rename from apishim/32/com/android/networkstack/apishim/SettingsShimImpl.java rename to apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java index 46d2102..cd3a463 100644 --- a/apishim/32/com/android/networkstack/apishim/SettingsShimImpl.java +++ b/apishim/33/com/android/networkstack/apishim/SettingsShimImpl.java
@@ -23,9 +23,9 @@ import com.android.networkstack.apishim.common.SettingsShim; /** - * Compatibility implementation of {@link SettingsShim} for API 31. + * Compatibility implementation of {@link SettingsShim} for API 33. */ -@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods +@RequiresApi(Build.VERSION_CODES.TIRAMISU) public class SettingsShimImpl extends com.android.networkstack.apishim.api30.SettingsShimImpl { // Currently identical to the API 31 shim, so inherit everything
diff --git a/apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java b/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java similarity index 91% rename from apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java rename to apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java index 2f4e500..d4ab534 100644 --- a/apishim/32/com/android/networkstack/apishim/SocketUtilsShimImpl.java +++ b/apishim/33/com/android/networkstack/apishim/SocketUtilsShimImpl.java
@@ -23,7 +23,7 @@ /** * Implementation of {@link com.android.networkstack.apishim.common.SocketUtilsShim}. */ -@RequiresApi(Build.VERSION_CODES.S) // Change to T when version code available, and adding T methods +@RequiresApi(Build.VERSION_CODES.TIRAMISU) public class SocketUtilsShimImpl extends com.android.networkstack.apishim.api30.SocketUtilsShimImpl { // Currently, this is the same as the API 31 shim, so inherit everything from that.
diff --git a/apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java b/apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java new file mode 100644 index 0000000..da8f774 --- /dev/null +++ b/apishim/33/com/android/networkstack/apishim/VpnServiceBuilderShimImpl.java
@@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.networkstack.apishim; + +import android.net.IpPrefix; +import android.net.VpnService; +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import com.android.modules.utils.build.SdkLevel; +import com.android.networkstack.apishim.common.UnsupportedApiLevelException; +import com.android.networkstack.apishim.common.VpnServiceBuilderShim; + +/** + * Implementation of {@link com.android.networkstack.apishim.common.VpnServiceBuilderShim}. + */ +@RequiresApi(Build.VERSION_CODES.TIRAMISU) +public class VpnServiceBuilderShimImpl extends + com.android.networkstack.apishim.api31.VpnServiceBuilderShimImpl { + + /** + * Get a new instance of {@link VpnServiceBuilderShim}. + */ + @RequiresApi(Build.VERSION_CODES.Q) + public static VpnServiceBuilderShim newInstance() { + if (SdkLevel.isAtLeastT()) { + return new VpnServiceBuilderShimImpl(); + } else { + return new com.android.networkstack.apishim.api31.VpnServiceBuilderShimImpl(); + } + } + + @Override + public VpnService.Builder excludeRoute(VpnService.Builder builder, IpPrefix prefix) + throws UnsupportedApiLevelException { + return builder.excludeRoute(prefix); + } + + @Override + public VpnService.Builder addRoute(VpnService.Builder builder, IpPrefix prefix) + throws UnsupportedApiLevelException { + return builder.addRoute(prefix); + } +}
diff --git a/apishim/common/com/android/networkstack/apishim/common/VpnServiceBuilderShim.java b/apishim/common/com/android/networkstack/apishim/common/VpnServiceBuilderShim.java new file mode 100644 index 0000000..fbfcf6c --- /dev/null +++ b/apishim/common/com/android/networkstack/apishim/common/VpnServiceBuilderShim.java
@@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.networkstack.apishim.common; + +import android.net.IpPrefix; +import android.net.VpnService; + +/** Shim for {@link VpnService.Builder}. */ +public interface VpnServiceBuilderShim { + /** + * @see VpnService.Builder#excludeRoute(IpPrefix) + */ + VpnService.Builder excludeRoute(VpnService.Builder builder, IpPrefix prefix) + throws UnsupportedApiLevelException; + + /** + * @see VpnService.Builder#addRoute(IpPrefix) + */ + VpnService.Builder addRoute(VpnService.Builder builder, IpPrefix prefix) + throws UnsupportedApiLevelException; +}
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp index fd7bfc9..3c97dc2 100644 --- a/common/networkstackclient/Android.bp +++ b/common/networkstackclient/Android.bp
@@ -35,7 +35,6 @@ apex_available: [ "//apex_available:platform", "com.android.wifi", - "com.android.bluetooth.updatable", "com.android.tethering", ], // this is part of updatable modules(NetworkStack) which targets 29(Q) @@ -109,7 +108,6 @@ java: { apex_available: [ "//apex_available:platform", - "com.android.bluetooth.updatable", "com.android.wifi", "com.android.tethering", ],
diff --git a/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java b/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java index d3e6cb7..7cf46f5 100644 --- a/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java +++ b/common/networkstackclient/src/android/net/ip/IpClientCallbacks.java
@@ -141,5 +141,9 @@ * * @param lossInfo the specific neighbor reachability loss information. */ - public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) {} + public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) { + // If the client does not implement this method, call the older + // onReachabilityLost method. + onReachabilityLost(lossInfo.message); + } }
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index e54f11c..706f174 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml
@@ -19,7 +19,7 @@ <string name="notification_channel_name_connected" msgid="1795068343200033922">"Godkendelse til loginportal"</string> <string name="notification_channel_description_connected" msgid="7239184168268014518">"De notifikationer, der vises, når enheden er blevet godkendt til et netværk via en loginportal"</string> <string name="notification_channel_name_network_venue_info" msgid="6526543187249265733">"Oplysninger om netværksplacering"</string> - <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Notifikationer, der vises for at indikere, at netværket har en side med oplysninger om placeringen"</string> + <string name="notification_channel_description_network_venue_info" msgid="5131499595382733605">"Notifikationer, der vises for at indikere, at netværket har en side med oplysninger om lokationen"</string> <string name="connected" msgid="4563643884927480998">"Der er oprettet forbindelse"</string> <string name="tap_for_info" msgid="6849746325626883711">"Der er oprettet forbindelse/tryk for at se website"</string> <string name="application_label" msgid="1322847171305285454">"Netværksadministrator"</string>
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java index d20e769..704ca7d 100644 --- a/src/android/net/dhcp/DhcpClient.java +++ b/src/android/net/dhcp/DhcpClient.java
@@ -251,6 +251,7 @@ public static final int DHCP_SUCCESS = 1; public static final int DHCP_FAILURE = 2; public static final int DHCP_IPV6_ONLY = 3; + public static final int DHCP_REFRESH_FAILURE = 4; // Internal messages. private static final int PRIVATE_BASE = IpClient.DHCPCLIENT_CMD_BASE + 100; @@ -391,6 +392,7 @@ private State mIpAddressConflictDetectingState = new IpAddressConflictDetectingState(); private State mDhcpDecliningState = new DhcpDecliningState(); private State mIpv6OnlyWaitState = new Ipv6OnlyWaitState(); + private State mDhcpRefreshingAddressState = new DhcpRefreshingAddressState(); private WakeupMessage makeWakeupMessage(String cmdName, int cmd) { cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName; @@ -499,6 +501,7 @@ addState(mDhcpRenewingState, mDhcpHaveLeaseState); addState(mDhcpRebindingState, mDhcpHaveLeaseState); addState(mDhcpDecliningState, mDhcpHaveLeaseState); + addState(mDhcpRefreshingAddressState, mDhcpHaveLeaseState); addState(mDhcpInitRebootState, mDhcpState); addState(mDhcpRebootingState, mDhcpState); // CHECKSTYLE:ON IndentationCheck @@ -849,11 +852,11 @@ CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease)); } - private void notifyFailure() { + private void notifyFailure(int arg) { if (isDhcpLeaseCacheEnabled()) { setLeaseExpiredToIpMemoryStore(); } - mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null); + mController.sendMessage(CMD_POST_DHCP_ACTION, arg, 0, null); } private void acceptDhcpResults(DhcpResults results, String msg) { @@ -1049,7 +1052,7 @@ if (mDhcpPacketHandler.start()) return; Log.e(TAG, "Fail to start DHCP Packet Handler"); } - notifyFailure(); + notifyFailure(DHCP_FAILURE); // We cannot call transitionTo because a transition is still in progress. // Instead, ensure that we process CMD_STOP_DHCP as soon as the transition is complete. deferMessage(obtainMessage(CMD_STOP_DHCP)); @@ -1454,7 +1457,7 @@ switch (message.what) { case CMD_EXPIRE_DHCP: Log.d(TAG, "Lease expired!"); - notifyFailure(); + notifyFailure(DHCP_FAILURE); transitionTo(mStoppedState); return HANDLED; default: @@ -1766,7 +1769,7 @@ // return an IPv4 address from another interface, or even return "0.0.0.0". // // TODO: Consider deleting this check, following testing on several kernels. - notifyFailure(); + notifyFailure(DHCP_FAILURE); transitionTo(mStoppedState); } @@ -1788,7 +1791,7 @@ preDhcpTransitionTo(mWaitBeforeRenewalState, mDhcpRenewingState); return HANDLED; case CMD_REFRESH_LINKADDRESS: - transitionTo(mDhcpRebindingState); + transitionTo(mDhcpRefreshingAddressState); return HANDLED; default: return NOT_HANDLED; @@ -1816,6 +1819,10 @@ protected abstract Inet4Address packetDestination(); + // Check whether DhcpClient should notify provisioning failure when receiving DHCPNAK + // in renew/rebind state or just restart reconfiguration from StoppedState. + protected abstract boolean shouldRestartOnNak(); + protected boolean sendPacket() { return sendRequestPacket( (Inet4Address) mDhcpLease.ipAddress.getAddress(), // ciaddr @@ -1834,7 +1841,7 @@ if (results != null) { if (!mDhcpLease.ipAddress.equals(results.ipAddress)) { Log.d(TAG, "Renewed lease not for our current IP address!"); - notifyFailure(); + notifyFailure(DHCP_FAILURE); transitionTo(mStoppedState); return; } @@ -1850,7 +1857,7 @@ } } else if (packet instanceof DhcpNakPacket) { Log.d(TAG, "Received NAK, returning to StoppedState"); - notifyFailure(); + notifyFailure(shouldRestartOnNak() ? DHCP_REFRESH_FAILURE : DHCP_FAILURE); transitionTo(mStoppedState); } } @@ -1883,6 +1890,11 @@ return (mDhcpLease.serverAddress != null) ? mDhcpLease.serverAddress : INADDR_BROADCAST; } + + @Override + protected boolean shouldRestartOnNak() { + return false; + } } class DhcpRebindingState extends DhcpReacquiringState { @@ -1907,6 +1919,22 @@ protected Inet4Address packetDestination() { return INADDR_BROADCAST; } + + @Override + protected boolean shouldRestartOnNak() { + return false; + } + } + + class DhcpRefreshingAddressState extends DhcpRebindingState { + DhcpRefreshingAddressState() { + mLeaseMsg = "Refreshing address"; + } + + @Override + protected boolean shouldRestartOnNak() { + return true; + } } class DhcpInitRebootState extends DhcpRequestingState {
diff --git a/src/android/net/dhcp/DhcpServingParams.java b/src/android/net/dhcp/DhcpServingParams.java index 0fd649d..9d395f7 100644 --- a/src/android/net/dhcp/DhcpServingParams.java +++ b/src/android/net/dhcp/DhcpServingParams.java
@@ -24,6 +24,7 @@ import static java.lang.Integer.toUnsignedLong; +import android.annotation.SuppressLint; import android.net.IpPrefix; import android.net.LinkAddress; import android.util.ArraySet; @@ -411,6 +412,7 @@ /** * Utility method to create an IpPrefix with the address and prefix length of a LinkAddress. */ + @SuppressLint("NewApi") @NonNull static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) { return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java index a81ab5c..00aa599 100644 --- a/src/android/net/ip/IpClient.java +++ b/src/android/net/ip/IpClient.java
@@ -21,6 +21,8 @@ import static android.net.ip.IIpClient.PROV_IPV4_DISABLED; import static android.net.ip.IIpClient.PROV_IPV6_DISABLED; import static android.net.ip.IIpClient.PROV_IPV6_LINKLOCAL; +import static android.net.ip.IpReachabilityMonitor.INVALID_REACHABILITY_LOSS_TYPE; +import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt; import static android.net.util.NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION; import static android.net.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION; import static android.net.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION; @@ -63,6 +65,8 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpManagerEvent; import android.net.networkstack.aidl.dhcp.DhcpOption; +import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable; +import android.net.networkstack.aidl.ip.ReachabilityLossReason; import android.net.shared.InitialConfiguration; import android.net.shared.Layer2Information; import android.net.shared.ProvisioningConfiguration; @@ -81,6 +85,7 @@ import android.os.SystemClock; import android.stats.connectivity.DisconnectCode; import android.stats.connectivity.NetworkQuirkEvent; +import android.stats.connectivity.NudEventType; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; @@ -316,6 +321,11 @@ /** * Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of * required neighbors (e.g. on-link default gw or dns servers) due to NUD_FAILED. + * + * Note this method is only supported on networkstack-aidl-interfaces-v12 or below. + * For above aidl versions, the caller should call {@link onReachabilityFailure} instead. + * For callbacks extending IpClientCallbacks, this method will be called iff the callback + * does not implement onReachabilityFailure. */ public void onReachabilityLost(String logMsg) { log("onReachabilityLost(" + logMsg + ")"); @@ -402,6 +412,20 @@ } /** + * Called when Neighbor Unreachability Detection fails, that might be caused by the organic + * probe or probeAll from IpReachabilityMonitor (if enabled). + */ + public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) { + log("onReachabilityFailure(" + lossInfo.message + ", loss reason: " + + reachabilityLossReasonToString(lossInfo.reason) + ")"); + try { + mCallback.onReachabilityFailure(lossInfo); + } catch (RemoteException e) { + log("Failed to call onReachabilityFailure", e); + } + } + + /** * Get the version of the IIpClientCallbacks AIDL interface. */ public int getInterfaceVersion() { @@ -478,6 +502,10 @@ private static final int PROV_CHANGE_GAINED_PROVISIONING = 3; private static final int PROV_CHANGE_STILL_PROVISIONED = 4; + // onReachabilityFailure callback is added since networkstack-aidl-interfaces-v13. + @VisibleForTesting + static final int VERSION_ADDED_REACHABILITY_FAILURE = 13; + // Specific vendor OUI(3 bytes)/vendor specific type(1 byte) pattern for upstream hotspot // device detection. Add new byte array pattern below in turn. private static final List<byte[]> METERED_IE_PATTERN_LIST = Collections.unmodifiableList( @@ -1250,6 +1278,20 @@ transitionTo(mStoppingState); } + // Convert reachability loss reason enum to a string. + private static String reachabilityLossReasonToString(int reason) { + switch (reason) { + case ReachabilityLossReason.ROAM: + return "reachability_loss_after_roam"; + case ReachabilityLossReason.CONFIRM: + return "reachability_loss_after_confirm"; + case ReachabilityLossReason.ORGANIC: + return "reachability_loss_organic"; + default: + return "unknown"; + } + } + private static boolean hasIpv6LinkLocalInterfaceRoute(final LinkProperties lp) { for (RouteInfo r : lp.getRoutes()) { if (r.getDestination().equals(new IpPrefix("fe80::/64")) @@ -1859,8 +1901,17 @@ mLog, new IpReachabilityMonitor.Callback() { @Override - public void notifyLost(InetAddress ip, String logMsg) { - mCallback.onReachabilityLost(logMsg); + public void notifyLost(InetAddress ip, String logMsg, NudEventType type) { + final int version = mCallback.getInterfaceVersion(); + if (version >= VERSION_ADDED_REACHABILITY_FAILURE) { + final int reason = nudEventTypeToInt(type); + if (reason == INVALID_REACHABILITY_LOSS_TYPE) return; + final ReachabilityLossInfoParcelable lossInfo = + new ReachabilityLossInfoParcelable(logMsg, reason); + mCallback.onReachabilityFailure(lossInfo); + } else { + mCallback.onReachabilityLost(logMsg); + } } }, mConfiguration.mUsingMultinetworkPolicyTracker, @@ -1938,18 +1989,18 @@ // If the BSSID has not changed, there is nothing to do. if (info.bssid.equals(mCurrentBssid)) return; - // Before trigger probing to the interesting neighbors, send Gratuitous ARP + // Before trigger probing to the critical neighbors, send Gratuitous ARP // and Neighbor Advertisment in advance to propgate host's IPv4/v6 addresses. if (isGratuitousArpNaRoamingEnabled()) { maybeSendGratuitousARP(mLinkProperties); maybeSendGratuitousNAs(mLinkProperties, true /* isGratuitousNaAfterRoaming */); } - if (mIpReachabilityMonitor != null) { - mIpReachabilityMonitor.probeAll(true /* dueToRoam */); - } - - // Check whether to refresh previous IP lease on L2 roaming happened. + // Check whether attempting to refresh previous IP lease on specific networks or need to + // probe the critical neighbors proactively on L2 roaming happened. The NUD probe on the + // specific networks is cancelled because otherwise the probe will happen in parallel with + // DHCP refresh, it will be difficult to understand what happened exactly and error-prone + // to introduce race condition. final String ssid = removeDoubleQuotes(mConfiguration.mDisplayName); if (DHCP_ROAMING_SSID_SET.contains(ssid) && mDhcpClient != null) { if (DBG) { @@ -1959,6 +2010,8 @@ + " , starting refresh leased IP address"); } mDhcpClient.sendMessage(DhcpClient.CMD_REFRESH_LINKADDRESS); + } else if (mIpReachabilityMonitor != null) { + mIpReachabilityMonitor.probeAll(true /* dueToRoam */); } mCurrentBssid = info.bssid; } @@ -2549,6 +2602,20 @@ break; case DhcpClient.DHCP_IPV6_ONLY: break; + case DhcpClient.DHCP_REFRESH_FAILURE: + // This case should only happen on the receipt of DHCPNAK when + // refreshing IP address post L2 roaming on some specific networks. + // WiFi should try to restart a new provisioning immediately without + // disconnecting L2 when it receives DHCP roaming failure event. IPv4 + // link address still will be cleared when DhcpClient transits to + // StoppedState from RefreshingAddress State, although it will result + // in a following onProvisioningFailure then, WiFi should ignore this + // failure and start a new DHCP reconfiguration from INIT state. + final ReachabilityLossInfoParcelable lossInfo = + new ReachabilityLossInfoParcelable("DHCP refresh failure", + ReachabilityLossReason.ROAM); + mCallback.onReachabilityFailure(lossInfo); + break; default: logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1); }
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java index 6b883f3..c716fdf 100644 --- a/src/android/net/ip/IpReachabilityMonitor.java +++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -32,6 +32,7 @@ import android.net.ip.IpNeighborMonitor.NeighborEventConsumer; import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpReachabilityEvent; +import android.net.networkstack.aidl.ip.ReachabilityLossReason; import android.net.util.InterfaceParams; import android.net.util.SharedLog; import android.os.ConditionVariable; @@ -157,6 +158,7 @@ private static final int INVALID_NUD_MCAST_RESOLICIT_NUM = -1; private static final int INVALID_LEGACY_NUD_FAILURE_TYPE = -1; + public static final int INVALID_REACHABILITY_LOSS_TYPE = -1; public interface Callback { /** @@ -165,7 +167,7 @@ * * TODO: refactor to something like notifyProvisioningLost(String msg). */ - void notifyLost(InetAddress ip, String logMsg); + void notifyLost(InetAddress ip, String logMsg, NudEventType type); } /** @@ -408,10 +410,11 @@ final String logMsg = "ALERT neighbor: " + event.ip + " MAC address changed from: " + prev.macAddr + " to: " + event.macAddr; + final NudEventType type = + getMacAddressChangedEventType(isFromProbe(), isNudFailureDueToRoam()); mLog.w(logMsg); - mCallback.notifyLost(event.ip, logMsg); - logNudFailed(event, - getMacAddressChangedEventType(isFromProbe(), isNudFailureDueToRoam())); + mCallback.notifyLost(event.ip, logMsg, type); + logNudFailed(event, type); return; } maybeRestoreNeighborParameters(); @@ -458,7 +461,7 @@ Log.w(TAG, logMsg); // TODO: remove |ip| when the callback signature no longer has // an InetAddress argument. - mCallback.notifyLost(ip, logMsg); + mCallback.notifyLost(ip, logMsg, type); } logNudFailed(event, type); } @@ -520,7 +523,9 @@ private long getProbeWakeLockDuration() { final long gracePeriodMs = 500; - return (long) (mNumSolicits * mInterSolicitIntervalMs) + gracePeriodMs; + final int numSolicits = + mNumSolicits + (isMulticastResolicitEnabled() ? NUD_MCAST_RESOLICIT_NUM : 0); + return (long) (numSolicits * mInterSolicitIntervalMs) + gracePeriodMs; } private void setNeighbourParametersPostRoaming() { @@ -571,7 +576,7 @@ } } - mNumSolicits = isMulticastResolicitEnabled() ? (numSolicits + numResolicits) : numSolicits; + mNumSolicits = numSolicits; mInterSolicitIntervalMs = interSolicitIntervalMs; } @@ -691,4 +696,24 @@ return INVALID_LEGACY_NUD_FAILURE_TYPE; } } + + /** + * Convert the NUD critical failure event type to a int constant defined in IIpClientCallbacks. + */ + public static int nudEventTypeToInt(final NudEventType type) { + switch (type) { + case NUD_POST_ROAMING_FAILED_CRITICAL: + case NUD_POST_ROAMING_MAC_ADDRESS_CHANGED: + return ReachabilityLossReason.ROAM; + case NUD_CONFIRM_FAILED_CRITICAL: + case NUD_CONFIRM_MAC_ADDRESS_CHANGED: + return ReachabilityLossReason.CONFIRM; + case NUD_ORGANIC_FAILED_CRITICAL: + case NUD_ORGANIC_MAC_ADDRESS_CHANGED: + return ReachabilityLossReason.ORGANIC; + // For other NudEventType which won't trigger notifyLost, just ignore these events. + default: + return INVALID_REACHABILITY_LOSS_TYPE; + } + } }
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt index 748ee5a..fa379d3 100644 --- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt +++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt
@@ -21,8 +21,6 @@ import android.net.ipmemorystore.Status import android.net.ipmemorystore.Status.SUCCESS import android.util.ArrayMap -import java.net.Inet6Address -import kotlin.test.assertEquals import org.mockito.Mockito.any import org.mockito.Mockito.doAnswer import org.mockito.ArgumentCaptor @@ -63,17 +61,6 @@ verify(mIpMemoryStore, never()).storeNetworkAttributes(eq(l2Key), any(), any()) } - override fun assertNotifyNeighborLost(targetIp: Inet6Address) { - val target = ArgumentCaptor.forClass(Inet6Address::class.java) - - verify(mCallback, timeout(TEST_TIMEOUT_MS)).notifyLost(target.capture(), any()) - assertEquals(targetIp, target.getValue()) - } - - override fun assertNeverNotifyNeighborLost() { - verify(mCallback, never()).notifyLost(any(), any()) - } - override fun storeNetworkAttributes(l2Key: String, na: NetworkAttributes) { doAnswer { inv -> val listener = inv.getArgument<OnNetworkAttributesRetrievedListener>(1)
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java index afe0990..22a4844 100644 --- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java +++ b/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java
@@ -29,8 +29,8 @@ import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable; import static android.net.ip.IpReachabilityMonitor.MIN_NUD_SOLICIT_NUM; import static android.net.ip.IpReachabilityMonitor.NUD_MCAST_RESOLICIT_NUM; +import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt; import static android.net.ipmemorystore.Status.SUCCESS; -import static android.net.shared.ProvisioningConfiguration.VERSION_ADDED_PROVISIONING_ENUM; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.IFA_F_TEMPORARY; import static android.system.OsConstants.IPPROTO_ICMPV6; @@ -125,6 +125,8 @@ import android.net.ipmemorystore.Status; import android.net.networkstack.TestNetworkStackServiceClient; import android.net.networkstack.aidl.dhcp.DhcpOption; +import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable; +import android.net.networkstack.aidl.ip.ReachabilityLossReason; import android.net.shared.Layer2Information; import android.net.shared.ProvisioningConfiguration; import android.net.shared.ProvisioningConfiguration.ScanResultInfo; @@ -141,6 +143,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.stats.connectivity.NetworkQuirkEvent; +import android.stats.connectivity.NudEventType; import android.system.ErrnoException; import android.system.Os; @@ -156,6 +159,7 @@ import com.android.net.module.util.structs.LlaOption; import com.android.net.module.util.structs.PrefixInformationOption; import com.android.net.module.util.structs.RdnssOption; +import com.android.networkstack.R; import com.android.networkstack.apishim.CaptivePortalDataShimImpl; import com.android.networkstack.apishim.ConstantsShim; import com.android.networkstack.apishim.common.ShimUtils; @@ -291,7 +295,6 @@ @Mock protected NetworkStackIpMemoryStore mIpMemoryStore; @Mock private NetworkQuirkMetrics.Dependencies mNetworkQuirkMetricsDeps; @Mock private IpReachabilityMonitorMetrics mIpReachabilityMonitorMetrics; - @Mock protected IpReachabilityMonitor.Callback mCallback; @Spy private INetd mNetd; private NetworkObserverRegistry mNetworkObserverRegistry; @@ -437,7 +440,7 @@ InterfaceParams ifParams, Handler h, SharedLog log, IpReachabilityMonitor.Callback callback, boolean usingMultinetworkPolicyTracker, IpReachabilityMonitor.Dependencies deps, final INetd netd) { - return new IpReachabilityMonitor(context, ifParams, h, log, mCallback, + return new IpReachabilityMonitor(context, ifParams, h, log, callback, usingMultinetworkPolicyTracker, deps, netd); } @@ -541,10 +544,6 @@ protected abstract void assertIpMemoryNeverStoreNetworkAttributes(String l2Key, long timeout); - protected abstract void assertNotifyNeighborLost(Inet6Address targetIp); - - protected abstract void assertNeverNotifyNeighborLost(); - protected final boolean testSkipped() { // TODO: split out a test suite for root tests, and fail hard instead of skipping the test // if it is run on devices where TestNetworkStackServiceClient is not supported @@ -607,10 +606,17 @@ when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm); when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm); when(mContext.getResources()).thenReturn(mResources); + when(mResources.getInteger(eq(R.integer.config_nud_postroaming_solicit_num))).thenReturn(5); + when(mResources.getInteger(eq(R.integer.config_nud_postroaming_solicit_interval))) + .thenReturn(750); + when(mResources.getInteger(eq(R.integer.config_nud_steadystate_solicit_num))) + .thenReturn(10); + when(mResources.getInteger(eq(R.integer.config_nud_steadystate_solicit_interval))) + .thenReturn(750); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mNetworkStackServiceManager.getIpMemoryStoreService()) .thenReturn(mIpMemoryStoreService); - when(mCb.getInterfaceVersion()).thenReturn(VERSION_ADDED_PROVISIONING_ENUM); + when(mCb.getInterfaceVersion()).thenReturn(IpClient.VERSION_ADDED_REACHABILITY_FAILURE); mDependencies.setDeviceConfigProperty(IpClient.CONFIG_MIN_RDNSS_LIFETIME, 67); mDependencies.setDeviceConfigProperty(DhcpClient.DHCP_RESTART_CONFIG_DELAY, 10); @@ -2546,12 +2552,23 @@ mPacketReader.sendResponse(packetBuffer); HandlerUtils.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS); - if (shouldReplyNakOnRoam || hasMismatchedIpAddress) { - // notifyFailure - ArgumentCaptor<DhcpResultsParcelable> captor = + if (shouldReplyNakOnRoam) { + ArgumentCaptor<ReachabilityLossInfoParcelable> lossInfoCaptor = + ArgumentCaptor.forClass(ReachabilityLossInfoParcelable.class); + verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityFailure(lossInfoCaptor.capture()); + assertEquals(ReachabilityLossReason.ROAM, lossInfoCaptor.getValue().reason); + + // IPv4 address will be still deleted when DhcpClient state machine exits from + // DhcpHaveLeaseState, a following onProvisioningFailure will be thrown then. + // Also check DhcpClient won't send any DHCPDISCOVER packet. + verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningFailure(any()); + assertNull(getNextDhcpPacket(TEST_TIMEOUT_MS)); + verify(mCb, never()).onNewDhcpResults(any()); + } else if (hasMismatchedIpAddress) { + ArgumentCaptor<DhcpResultsParcelable> resultsCaptor = ArgumentCaptor.forClass(DhcpResultsParcelable.class); - verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(captor.capture()); - DhcpResults lease = fromStableParcelable(captor.getValue()); + verify(mCb, timeout(TEST_TIMEOUT_MS)).onNewDhcpResults(resultsCaptor.capture()); + DhcpResults lease = fromStableParcelable(resultsCaptor.getValue()); assertNull(lease); // DhcpClient rolls back to StoppedState instead of INIT state after calling @@ -3459,6 +3476,38 @@ prepareIpReachabilityMonitorTest(false /* isMulticastResolicitEnabled */); } + private void assertNotifyNeighborLost(Inet6Address targetIp, NudEventType eventType) + throws Exception { + // For root test suite, rely on the IIpClient aidl interface version constant defined in + // {@link IpClientRootTest.BinderCbWrapper}; for privileged integration test suite that + // requires signature permission, use the mocked aidl version defined in {@link setUpMocks}, + // which results in only new callbacks are verified. And add separate test cases to test the + // legacy callbacks explicitly as well. + assertNeighborReachabilityLoss(targetIp, eventType, + useNetworkStackSignature() + ? IpClient.VERSION_ADDED_REACHABILITY_FAILURE + : mIIpClient.getInterfaceVersion()); + } + + private void assertNeighborReachabilityLoss(Inet6Address targetIp, NudEventType eventType, + int targetAidlVersion) throws Exception { + if (targetAidlVersion >= IpClient.VERSION_ADDED_REACHABILITY_FAILURE) { + final ArgumentCaptor<ReachabilityLossInfoParcelable> lossInfoCaptor = + ArgumentCaptor.forClass(ReachabilityLossInfoParcelable.class); + verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityFailure(lossInfoCaptor.capture()); + assertEquals(nudEventTypeToInt(eventType), lossInfoCaptor.getValue().reason); + verify(mCb, never()).onReachabilityLost(any()); + } else { + verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any()); + verify(mCb, never()).onReachabilityFailure(any()); + } + } + + private void assertNeverNotifyNeighborLost() throws Exception { + verify(mCb, never()).onReachabilityFailure(any()); + verify(mCb, never()).onReachabilityLost(any()); + } + private void prepareIpReachabilityMonitorTest(boolean isMulticastResolicitEnabled) throws Exception { final ScanResultInfo info = makeScanResultInfo(TEST_DEFAULT_SSID, TEST_DEFAULT_BSSID); @@ -3479,8 +3528,7 @@ forceLayer2Roaming(); } - @Test - public void testIpReachabilityMonitor_probeFailed() throws Exception { + private void runIpReachabilityMonitorProbeFailedTest() throws Exception { prepareIpReachabilityMonitorTest(); final List<NeighborSolicitation> nsList = waitForMultipleNeighborSolicitations(); @@ -3489,7 +3537,22 @@ assertUnicastNeighborSolicitation(ns, ROUTER_MAC /* dstMac */, ROUTER_LINK_LOCAL /* dstIp */, ROUTER_LINK_LOCAL /* targetIp */); } - assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */); + } + + @Test + public void testIpReachabilityMonitor_probeFailed() throws Exception { + runIpReachabilityMonitorProbeFailedTest(); + assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */, + NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL); + } + + @Test @SignatureRequiredTest(reason = "requires mock callback object") + public void testIpReachabilityMonitor_probeFailed_legacyCallback() throws Exception { + when(mCb.getInterfaceVersion()).thenReturn(12 /* assign an older interface aidl version */); + + runIpReachabilityMonitorProbeFailedTest(); + verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any()); + verify(mCb, never()).onReachabilityFailure(any()); } @Test @@ -3508,8 +3571,7 @@ assertNeverNotifyNeighborLost(); } - @Test - public void testIpReachabilityMonitor_mcastResoclicitProbeFailed() throws Exception { + private void runIpReachabilityMonitorMcastResolicitProbeFailedTest() throws Exception { prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */); final List<NeighborSolicitation> nsList = waitForMultipleNeighborSolicitations(); @@ -3522,11 +3584,27 @@ for (NeighborSolicitation ns : nsList.subList(MIN_NUD_SOLICIT_NUM, nsList.size())) { assertMulticastNeighborSolicitation(ns, ROUTER_LINK_LOCAL /* targetIp */); } - assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */); } @Test - public void testIpReachabilityMonitor_mcastResoclicitProbeReachableWithSameLinkLayerAddress() + public void testIpReachabilityMonitor_mcastResolicitProbeFailed() throws Exception { + runIpReachabilityMonitorMcastResolicitProbeFailedTest(); + assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */, + NudEventType.NUD_POST_ROAMING_FAILED_CRITICAL); + } + + @Test @SignatureRequiredTest(reason = "requires mock callback object") + public void testIpReachabilityMonitor_mcastResolicitProbeFailed_legacyCallback() + throws Exception { + when(mCb.getInterfaceVersion()).thenReturn(12 /* assign an older interface aidl version */); + + runIpReachabilityMonitorMcastResolicitProbeFailedTest(); + verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(any()); + verify(mCb, never()).onReachabilityFailure(any()); + } + + @Test + public void testIpReachabilityMonitor_mcastResolicitProbeReachableWithSameLinkLayerAddress() throws Exception { prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */); @@ -3543,7 +3621,7 @@ } @Test - public void testIpReachabilityMonitor_mcastResoclicitProbeReachableWithDiffLinkLayerAddress() + public void testIpReachabilityMonitor_mcastResolicitProbeReachableWithDiffLinkLayerAddress() throws Exception { prepareIpReachabilityMonitorTest(true /* isMulticastResolicitEnabled */); @@ -3562,7 +3640,8 @@ ns.ethHdr.srcMac /* dstMac */, ROUTER_LINK_LOCAL /* srcIp */, ns.ipv6Hdr.srcIp /* dstIp */, flag, ROUTER_LINK_LOCAL /* target */); mPacketReader.sendResponse(na); - assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */); + assertNotifyNeighborLost(ROUTER_LINK_LOCAL /* targetIp */, + NudEventType.NUD_POST_ROAMING_MAC_ADDRESS_CHANGED); } @Test
diff --git a/tests/integration/src/android/net/ip/IpClientRootTest.kt b/tests/integration/src/android/net/ip/IpClientRootTest.kt index d861639..7359e05 100644 --- a/tests/integration/src/android/net/ip/IpClientRootTest.kt +++ b/tests/integration/src/android/net/ip/IpClientRootTest.kt
@@ -33,7 +33,6 @@ import androidx.test.platform.app.InstrumentationRegistry import com.android.net.module.util.DeviceConfigUtils import java.lang.System.currentTimeMillis -import java.net.Inet6Address import java.util.concurrent.CompletableFuture import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit @@ -46,8 +45,6 @@ import org.junit.AfterClass import org.junit.BeforeClass import org.mockito.ArgumentCaptor -import org.mockito.Mockito.anyString -import org.mockito.Mockito.never import org.mockito.Mockito.timeout import org.mockito.Mockito.verify @@ -265,14 +262,6 @@ assertNull(listener.getBlockingNetworkAttributes(timeout)) } - override fun assertNotifyNeighborLost(targetIp: Inet6Address) { - verify(mCb, timeout(TEST_TIMEOUT_MS)).onReachabilityLost(anyString()) - } - - override fun assertNeverNotifyNeighborLost() { - verify(mCb, never()).onReachabilityLost(anyString()) - } - override fun storeNetworkAttributes(l2Key: String, na: NetworkAttributes) { mStore.storeNetworkAttributes(l2Key, na, null /* listener */) }
diff --git a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java index 7b0af69..b9b1652 100644 --- a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java +++ b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
@@ -45,6 +45,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.net.IpPrefix; import android.net.MacAddress; import android.net.dhcp.DhcpServer.Clock; @@ -84,6 +85,7 @@ private static final Inet4Address TEST_INETADDR_2 = parseAddr4("192.168.42.249"); private static final String TEST_HOSTNAME_1 = "hostname1"; private static final String TEST_HOSTNAME_2 = "hostname2"; + @SuppressLint("NewApi") private static final IpPrefix TEST_IP_PREFIX = new IpPrefix(TEST_SERVER_ADDR, 22); private static final long TEST_TIME = 100L; private static final int TEST_LEASE_TIME_MS = 3_600_000; @@ -149,6 +151,7 @@ } } + @SuppressLint("NewApi") @Test public void testAddressExhaustion() throws Exception { // Use a /28 to quickly run out of addresses @@ -169,6 +172,7 @@ verifyNoMoreInteractions(mCallbacks); } + @SuppressLint("NewApi") @Test public void testUpdateParams_LeaseCleanup() throws Exception { // Inside /28: @@ -229,6 +233,7 @@ } } + @SuppressLint("NewApi") @Test public void testUpdateParams_UsesNewPrefix() throws Exception { final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24); @@ -538,6 +543,7 @@ assertNotEquals(lease.getNetAddr(), newLease.getNetAddr()); } + @SuppressLint("NewApi") @Test public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception { // Use a /28 to quickly run out of addresses
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java index 173a9e1..37f12ca 100644 --- a/tests/unit/src/android/net/ip/IpClientTest.java +++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -40,6 +40,7 @@ import static java.util.Collections.emptySet; +import android.annotation.SuppressLint; import android.app.AlarmManager; import android.content.ContentResolver; import android.content.Context; @@ -296,6 +297,7 @@ return ipc; } + @SuppressLint("NewApi") private void addIPv4Provisioning(LinkProperties lp) { final LinkAddress la = new LinkAddress(TEST_IPV4_LINKADDRESS); final RouteInfo defaultRoute = new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), @@ -625,6 +627,7 @@ TEST_IFNAME)); } + @SuppressLint("NewApi") static RouteInfo defaultIPV6Route(String gateway) { return new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), InetAddresses.parseNumericAddress(gateway), TEST_IFNAME);
diff --git a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt index 5245cc3..0109022 100644 --- a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt +++ b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
@@ -15,6 +15,7 @@ */ package android.net.ip +import android.annotation.SuppressLint import android.content.Context import android.net.ip.IpNeighborMonitor.NeighborEventConsumer import android.net.INetd @@ -106,6 +107,8 @@ private val TEST_IPV6_DNS2 = parseNumericAddress("2001:db8::456") as Inet6Address private val TEST_IFACE = InterfaceParams("fake0", 21, null) + +@SuppressLint("NewApi") private val TEST_LINK_PROPERTIES = LinkProperties().apply { interfaceName = TEST_IFACE.name addLinkAddress(TEST_IPV4_LINKADDR) @@ -123,6 +126,7 @@ addDnsServer(TEST_IPV6_DNS) } +@SuppressLint("NewApi") private val TEST_IPV4_ONLY_LINK_PROPERTIES = LinkProperties().apply { interfaceName = TEST_IFACE.name addLinkAddress(TEST_IPV4_LINKADDR) @@ -136,6 +140,7 @@ addDnsServer(TEST_IPV4_GATEWAY_DNS) } +@SuppressLint("NewApi") private val TEST_IPV6_LINKLOCAL_SCOPED_LINK_PROPERTIES = LinkProperties().apply { interfaceName = TEST_IFACE.name addLinkAddress(TEST_IPV6_LINKADDR) @@ -151,6 +156,7 @@ addDnsServer(TEST_IPV6_DNS) } +@SuppressLint("NewApi") private val TEST_DUAL_LINK_PROPERTIES = LinkProperties().apply { interfaceName = TEST_IFACE.name addLinkAddress(TEST_IPV4_LINKADDR) @@ -287,10 +293,15 @@ reachabilityMonitor.updateLinkProperties(TEST_LINK_PROPERTIES) neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_DNS, NUD_FAILED)) - verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(TEST_IPV4_DNS), anyString()) + verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(TEST_IPV4_DNS), anyString(), + eq(NUD_ORGANIC_FAILED_CRITICAL)) } - private fun runLoseProvisioningTest(newLp: LinkProperties, lostNeighbor: InetAddress) { + private fun runLoseProvisioningTest( + newLp: LinkProperties, + lostNeighbor: InetAddress, + eventType: NudEventType + ) { reachabilityMonitor.updateLinkProperties(newLp) neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV4_GATEWAY, NUD_STALE)) @@ -299,7 +310,8 @@ neighborMonitor.enqueuePacket(makeNewNeighMessage(TEST_IPV6_DNS, NUD_STALE)) neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED)) - verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(lostNeighbor), anyString()) + verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(lostNeighbor), anyString(), + eq(eventType)) } private fun verifyNudFailureMetrics( @@ -327,7 +339,7 @@ neighborMonitor.enqueuePacket(makeNewNeighMessage(lostNeighbor, NUD_FAILED)) handlerThread.waitForIdle(TEST_TIMEOUT_MS) - verify(callback, never()).notifyLost(any(), anyString()) + verify(callback, never()).notifyLost(any(), anyString(), any(NudEventType::class.java)) verifyNudFailureMetrics(eventType, ipType, lostNeighborType) } @@ -343,27 +355,30 @@ neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, "001122334455" /* oldMac */)) handlerThread.waitForIdle(TEST_TIMEOUT_MS) - verify(callback, never()).notifyLost(eq(neighbor), anyString()) + verify(callback, never()).notifyLost(eq(neighbor), anyString(), + any(NudEventType::class.java)) } @Test fun testLoseProvisioning_Ipv4DnsLost() { - runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS) + runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_DNS, NUD_ORGANIC_FAILED_CRITICAL) } @Test fun testLoseProvisioning_Ipv6DnsLost() { - runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS) + runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_DNS, NUD_ORGANIC_FAILED_CRITICAL) } @Test fun testLoseProvisioning_Ipv4GatewayLost() { - runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY) + runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV4_GATEWAY, + NUD_ORGANIC_FAILED_CRITICAL) } @Test fun testLoseProvisioning_Ipv6GatewayLost() { - runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY) + runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY, + NUD_ORGANIC_FAILED_CRITICAL) } private fun runNudProbeFailureMetricsTest( @@ -373,7 +388,7 @@ ipType: IpType, lostNeighborType: NudNeighborType ) { - runLoseProvisioningTest(lp, lostNeighbor) + runLoseProvisioningTest(lp, lostNeighbor, eventType) verifyNudFailureMetrics(eventType, ipType, lostNeighborType) } @@ -526,7 +541,8 @@ handlerThread.waitForIdle(TEST_TIMEOUT_MS) Thread.sleep(2) reachabilityMonitor.probeAll(false /* dueToRoam */) - runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY) + runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY, + NUD_POST_ROAMING_FAILED_CRITICAL) verifyNudFailureMetrics(NUD_POST_ROAMING_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY) } @@ -537,7 +553,8 @@ handlerThread.waitForIdle(TEST_TIMEOUT_MS) Thread.sleep(2) reachabilityMonitor.probeAll(true /* dueToRoam */) - runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY) + runLoseProvisioningTest(TEST_LINK_PROPERTIES, TEST_IPV6_GATEWAY, + NUD_CONFIRM_FAILED_CRITICAL) verifyNudFailureMetrics(NUD_CONFIRM_FAILED_CRITICAL, IPV6, NUD_NEIGHBOR_GATEWAY) } @@ -549,7 +566,8 @@ ) { neighborMonitor.enqueuePacket(makeNewNeighMessage(neighbor, NUD_REACHABLE, "1122334455aa" /* newMac */)) - verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(neighbor), anyString()) + verify(callback, timeout(TEST_TIMEOUT_MS)).notifyLost(eq(neighbor), anyString(), + eq(eventType)) verifyNudFailureMetrics(eventType, ipType, NUD_NEIGHBOR_GATEWAY) }
diff --git a/tests/unit/src/android/net/shared/InitialConfigurationTest.java b/tests/unit/src/android/net/shared/InitialConfigurationTest.java index 4d5a7df..0ec0053 100644 --- a/tests/unit/src/android/net/shared/InitialConfigurationTest.java +++ b/tests/unit/src/android/net/shared/InitialConfigurationTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import android.annotation.SuppressLint; import android.net.IpPrefix; import android.net.LinkAddress; @@ -44,6 +45,7 @@ public class InitialConfigurationTest { private InitialConfiguration mConfig; + @SuppressLint("NewApi") @Before public void setUp() { mConfig = new InitialConfiguration(); @@ -67,6 +69,7 @@ assertEquals(mConfig, unparceled); } + @SuppressLint("NewApi") @Test public void testEquals() { assertEquals(mConfig, InitialConfiguration.copy(mConfig));