Merge "Prevent race in NetworkMonitorTest" into rvc-dev
diff --git a/Android.bp b/Android.bp
index ccdaf7a..04b1062 100644
--- a/Android.bp
+++ b/Android.bp
@@ -214,7 +214,10 @@
defaults: ["NetworkStackAppDefaults", "NetworkStackReleaseApiLevel"],
static_libs: ["NetworkStackApiStableLib"],
manifest: "AndroidManifestBase.xml",
- visibility: ["//frameworks/base/tests/net/integration"],
+ visibility: [
+ "//frameworks/base/tests/net/integration",
+ "//cts/tests/tests/net",
+ ],
}
cc_library_shared {
diff --git a/apishim/30/com/android/networkstack/apishim/api30/ConstantsShim.java b/apishim/30/com/android/networkstack/apishim/api30/ConstantsShim.java
index eb4fc07..27fd745 100644
--- a/apishim/30/com/android/networkstack/apishim/api30/ConstantsShim.java
+++ b/apishim/30/com/android/networkstack/apishim/api30/ConstantsShim.java
@@ -37,4 +37,9 @@
DataStallReport.DETECTION_METHOD_DNS_EVENTS;
public static final int DETECTION_METHOD_TCP_METRICS =
DataStallReport.DETECTION_METHOD_TCP_METRICS;
+
+ /**
+ * @see android.net.NetworkCapabilities
+ */
+ public static final int TRANSPORT_TEST = 7;
}
diff --git a/apishim/31/com/android/networkstack/apishim/ConstantsShim.java b/apishim/31/com/android/networkstack/apishim/ConstantsShim.java
index a328720..0184845 100644
--- a/apishim/31/com/android/networkstack/apishim/ConstantsShim.java
+++ b/apishim/31/com/android/networkstack/apishim/ConstantsShim.java
@@ -30,4 +30,8 @@
*/
@VisibleForTesting
public static final int VERSION = 31;
+
+ // When removing this shim, the version in NetworkMonitorUtils should be removed too.
+ // TODO: add TRANSPORT_TEST to system API in API 31 (it is only a test API as of R)
+ public static final int TRANSPORT_TEST = 7;
}
diff --git a/common/moduleutils/src/android/net/shared/Layer2Information.java b/common/moduleutils/src/android/net/shared/Layer2Information.java
index fa4f102..8cdd018 100644
--- a/common/moduleutils/src/android/net/shared/Layer2Information.java
+++ b/common/moduleutils/src/android/net/shared/Layer2Information.java
@@ -27,17 +27,17 @@
@Nullable
public final String mL2Key;
@Nullable
- public final String mGroupHint;
+ public final String mCluster;
@Nullable
public final MacAddress mBssid;
/**
* Create a Layer2Information with the specified configuration.
*/
- public Layer2Information(@Nullable final String l2Key, @Nullable final String groupHint,
+ public Layer2Information(@Nullable final String l2Key, @Nullable final String cluster,
@Nullable final MacAddress bssid) {
mL2Key = l2Key;
- mGroupHint = groupHint;
+ mCluster = cluster;
mBssid = bssid;
}
@@ -45,7 +45,7 @@
public String toString() {
StringBuffer str = new StringBuffer();
str.append("L2Key: ").append(mL2Key);
- str.append(", GroupHint: ").append(mGroupHint);
+ str.append(", Cluster: ").append(mCluster);
str.append(", bssid: ").append(mBssid);
return str.toString();
}
@@ -56,7 +56,7 @@
public Layer2InformationParcelable toStableParcelable() {
final Layer2InformationParcelable p = new Layer2InformationParcelable();
p.l2Key = mL2Key;
- p.groupHint = mGroupHint;
+ p.cluster = mCluster;
p.bssid = mBssid;
return p;
}
@@ -67,7 +67,7 @@
*/
public static Layer2Information fromStableParcelable(Layer2InformationParcelable p) {
if (p == null) return null;
- return new Layer2Information(p.l2Key, p.groupHint, p.bssid);
+ return new Layer2Information(p.l2Key, p.cluster, p.bssid);
}
@Override
@@ -75,12 +75,12 @@
if (!(obj instanceof Layer2Information)) return false;
final Layer2Information other = (Layer2Information) obj;
return Objects.equals(mL2Key, other.mL2Key)
- && Objects.equals(mGroupHint, other.mGroupHint)
+ && Objects.equals(mCluster, other.mCluster)
&& Objects.equals(mBssid, other.mBssid);
}
@Override
public int hashCode() {
- return Objects.hash(mL2Key, mGroupHint, mBssid);
+ return Objects.hash(mL2Key, mCluster, mBssid);
}
}
diff --git a/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java b/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java
index 8983d00..981a576 100644
--- a/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java
+++ b/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java
@@ -20,11 +20,21 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import android.net.NetworkCapabilities;
/** @hide */
public class NetworkMonitorUtils {
+ // This class is used by both NetworkMonitor and ConnectivityService, so it cannot use
+ // NetworkStack shims, but at the same time cannot use non-system APIs.
+ // TRANSPORT_TEST is test API as of R (so it is enforced to always be 7 and can't be changed),
+ // and it is being added as a system API in S.
+ // TODO: use NetworkCapabilities.TRANSPORT_TEST once NetworkStack builds against API 31.
+ private static final int TRANSPORT_TEST = 7;
// Network conditions broadcast constants
public static final String ACTION_NETWORK_CONDITIONS_MEASURED =
@@ -47,11 +57,33 @@
* @param nc Network capabilities of the network to test.
*/
public static boolean isPrivateDnsValidationRequired(NetworkCapabilities nc) {
+ if (nc == null) return false;
+
// TODO: Consider requiring validation for DUN networks.
- return nc != null
- && nc.hasCapability(NET_CAPABILITY_INTERNET)
+ if (nc.hasCapability(NET_CAPABILITY_INTERNET)
&& nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
- && nc.hasCapability(NET_CAPABILITY_TRUSTED);
+ && nc.hasCapability(NET_CAPABILITY_TRUSTED)) {
+ // Real networks
+ return true;
+ }
+
+ // TODO: once TRANSPORT_TEST is @SystemApi in S and S SDK is stable (so constant shims can
+ // be replaced with the SDK constant that will be inlined), replace isTestNetwork with
+ // hasTransport(TRANSPORT_TEST)
+
+ // Test networks that also have one of the major transport types are attempting to replicate
+ // that transport on a test interface (for example, test ethernet networks with
+ // EthernetManager#setIncludeTestInterfaces). Run validation on them for realistic tests.
+ // See also comments on EthernetManager#setIncludeTestInterfaces and on TestNetworkManager.
+ if (nc.hasTransport(TRANSPORT_TEST) && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) && (
+ nc.hasTransport(TRANSPORT_WIFI)
+ || nc.hasTransport(TRANSPORT_CELLULAR)
+ || nc.hasTransport(TRANSPORT_BLUETOOTH)
+ || nc.hasTransport(TRANSPORT_ETHERNET))) {
+ return true;
+ }
+
+ return false;
}
/**
diff --git a/common/moduleutils/src/android/net/shared/ProvisioningConfiguration.java b/common/moduleutils/src/android/net/shared/ProvisioningConfiguration.java
index 9849eff..cb613fb 100644
--- a/common/moduleutils/src/android/net/shared/ProvisioningConfiguration.java
+++ b/common/moduleutils/src/android/net/shared/ProvisioningConfiguration.java
@@ -219,7 +219,7 @@
}
/**
- * Specify the L2 information(bssid, l2key and groupHint) that the IpClient should use.
+ * Specify the L2 information(bssid, l2key and cluster) that the IpClient should use.
*/
public Builder withLayer2Information(Layer2Information layer2Info) {
mConfig.mLayer2Info = layer2Info;
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp
index 7c4b8d5..3ddf633 100644
--- a/common/networkstackclient/Android.bp
+++ b/common/networkstackclient/Android.bp
@@ -43,6 +43,8 @@
"3",
"4",
"5",
+ "6",
+ "7",
],
visibility: [
"//system/tools/aidl/build",
@@ -105,6 +107,7 @@
"4",
"5",
"6",
+ "7",
],
// TODO: have tethering depend on networkstack-client and set visibility to private
visibility: [
@@ -123,7 +126,7 @@
"src/android/net/networkstack/**/*.java",
],
static_libs: [
- "ipmemorystore-aidl-interfaces-V5-java",
+ "ipmemorystore-aidl-interfaces-java",
"networkstack-aidl-interfaces-java",
],
visibility: [
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/.hash b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/.hash
new file mode 100644
index 0000000..471d984
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/.hash
@@ -0,0 +1 @@
+995043fb16c363208cbdb99c48bb775040d1f169
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/IIpMemoryStore.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/IIpMemoryStore.aidl
new file mode 100644
index 0000000..ac87e59
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/IIpMemoryStore.aidl
@@ -0,0 +1,28 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface IIpMemoryStore {
+ oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
+ oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
+ oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
+ oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
+ oneway void factoryReset();
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/IIpMemoryStoreCallbacks.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/IIpMemoryStoreCallbacks.aidl
new file mode 100644
index 0000000..2024391
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/IIpMemoryStoreCallbacks.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface IIpMemoryStoreCallbacks {
+ oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/Blob.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/Blob.aidl
new file mode 100644
index 0000000..8a1b57e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/Blob.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable Blob {
+ byte[] data;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
new file mode 100644
index 0000000..e711272
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnBlobRetrievedListener {
+ oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
new file mode 100644
index 0000000..4abecb9
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnL2KeyResponseListener {
+ oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
new file mode 100644
index 0000000..05c48b3
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnNetworkAttributesRetrievedListener {
+ oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
new file mode 100644
index 0000000..0bc8c5e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnSameL3NetworkResponseListener {
+ oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnStatusListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnStatusListener.aidl
new file mode 100644
index 0000000..e71de47
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnStatusListener {
+ oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
new file mode 100644
index 0000000..92a570d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable NetworkAttributesParcelable {
+ byte[] assignedV4Address;
+ long assignedV4AddressExpiry;
+ String cluster;
+ android.net.ipmemorystore.Blob[] dnsAddresses;
+ int mtu;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
new file mode 100644
index 0000000..eca0987
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable SameL3NetworkResponseParcelable {
+ String l2Key1;
+ String l2Key2;
+ float confidence;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/StatusParcelable.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/StatusParcelable.aidl
new file mode 100644
index 0000000..7554608
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/6/android/net/ipmemorystore/StatusParcelable.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable StatusParcelable {
+ int resultCode;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/.hash b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/.hash
new file mode 100644
index 0000000..786a6f7
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/.hash
@@ -0,0 +1 @@
+31826566143ef882d67fac9f24566f73df4907b4
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/IIpMemoryStore.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/IIpMemoryStore.aidl
new file mode 100644
index 0000000..bf7a26d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/IIpMemoryStore.aidl
@@ -0,0 +1,30 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface IIpMemoryStore {
+ oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
+ oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
+ oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
+ oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
+ oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
+ oneway void factoryReset();
+ oneway void delete(String l2Key, boolean needWipe, android.net.ipmemorystore.IOnStatusAndCountListener listener);
+ oneway void deleteCluster(String cluster, boolean needWipe, android.net.ipmemorystore.IOnStatusAndCountListener listener);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/IIpMemoryStoreCallbacks.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/IIpMemoryStoreCallbacks.aidl
new file mode 100644
index 0000000..2024391
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/IIpMemoryStoreCallbacks.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface IIpMemoryStoreCallbacks {
+ oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/Blob.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/Blob.aidl
new file mode 100644
index 0000000..8a1b57e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/Blob.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable Blob {
+ byte[] data;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
new file mode 100644
index 0000000..e711272
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnBlobRetrievedListener {
+ oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
new file mode 100644
index 0000000..4abecb9
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnL2KeyResponseListener {
+ oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
new file mode 100644
index 0000000..05c48b3
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnNetworkAttributesRetrievedListener {
+ oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
new file mode 100644
index 0000000..0bc8c5e
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnSameL3NetworkResponseListener {
+ oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnStatusAndCountListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnStatusAndCountListener.aidl
new file mode 100644
index 0000000..cf30fa1
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnStatusAndCountListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnStatusAndCountListener {
+ oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status, int count);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnStatusListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnStatusListener.aidl
new file mode 100644
index 0000000..e71de47
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnStatusListener {
+ oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
new file mode 100644
index 0000000..92a570d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable NetworkAttributesParcelable {
+ byte[] assignedV4Address;
+ long assignedV4AddressExpiry;
+ String cluster;
+ android.net.ipmemorystore.Blob[] dnsAddresses;
+ int mtu;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
new file mode 100644
index 0000000..eca0987
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable SameL3NetworkResponseParcelable {
+ String l2Key1;
+ String l2Key2;
+ float confidence;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/StatusParcelable.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/StatusParcelable.aidl
new file mode 100644
index 0000000..7554608
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/7/android/net/ipmemorystore/StatusParcelable.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+parcelable StatusParcelable {
+ int resultCode;
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/IIpMemoryStore.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/IIpMemoryStore.aidl
index ac87e59..bf7a26d 100644
--- a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/IIpMemoryStore.aidl
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/IIpMemoryStore.aidl
@@ -25,4 +25,6 @@
oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
oneway void factoryReset();
+ oneway void delete(String l2Key, boolean needWipe, android.net.ipmemorystore.IOnStatusAndCountListener listener);
+ oneway void deleteCluster(String cluster, boolean needWipe, android.net.ipmemorystore.IOnStatusAndCountListener listener);
}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/ipmemorystore/IOnStatusAndCountListener.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/ipmemorystore/IOnStatusAndCountListener.aidl
new file mode 100644
index 0000000..cf30fa1
--- /dev/null
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/ipmemorystore/IOnStatusAndCountListener.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ipmemorystore;
+/* @hide */
+interface IOnStatusAndCountListener {
+ oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status, int count);
+}
diff --git a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
index 76aa257..92a570d 100644
--- a/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ b/common/networkstackclient/aidl_api/ipmemorystore-aidl-interfaces/current/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -20,7 +20,7 @@
parcelable NetworkAttributesParcelable {
byte[] assignedV4Address;
long assignedV4AddressExpiry;
- String groupHint;
+ String cluster;
android.net.ipmemorystore.Blob[] dnsAddresses;
int mtu;
}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/.hash b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/.hash
new file mode 100644
index 0000000..16f2421
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/.hash
@@ -0,0 +1 @@
+02cd6fd07d5c04eca0c35a350f7b0be576242883
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/DataStallReportParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/DataStallReportParcelable.aidl
new file mode 100644
index 0000000..69ff31f
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/DataStallReportParcelable.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable DataStallReportParcelable {
+ long timestampMillis = 0;
+ int detectionMethod = 1;
+ int tcpPacketFailRate = 2;
+ int tcpMetricsCollectionPeriodMillis = 3;
+ int dnsConsecutiveTimeouts = 4;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/DhcpResultsParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/DhcpResultsParcelable.aidl
new file mode 100644
index 0000000..7bb5c41
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/DhcpResultsParcelable.aidl
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable DhcpResultsParcelable {
+ android.net.StaticIpConfiguration baseConfiguration;
+ int leaseDuration;
+ int mtu;
+ String serverAddress;
+ String vendorInfo;
+ @nullable String serverHostName;
+ @nullable String captivePortalApiUrl;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkMonitor.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkMonitor.aidl
new file mode 100644
index 0000000..5945819
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkMonitor.aidl
@@ -0,0 +1,42 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkMonitor {
+ oneway void start();
+ oneway void launchCaptivePortalApp();
+ oneway void notifyCaptivePortalAppFinished(int response);
+ oneway void setAcceptPartialConnectivity();
+ oneway void forceReevaluation(int uid);
+ oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
+ oneway void notifyDnsResponse(int returnCode);
+ oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
+ oneway void notifyNetworkDisconnected();
+ oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
+ oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
+ const int NETWORK_TEST_RESULT_VALID = 0;
+ const int NETWORK_TEST_RESULT_INVALID = 1;
+ const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
+ const int NETWORK_VALIDATION_RESULT_VALID = 1;
+ const int NETWORK_VALIDATION_RESULT_PARTIAL = 2;
+ const int NETWORK_VALIDATION_PROBE_DNS = 4;
+ const int NETWORK_VALIDATION_PROBE_HTTP = 8;
+ const int NETWORK_VALIDATION_PROBE_HTTPS = 16;
+ const int NETWORK_VALIDATION_PROBE_FALLBACK = 32;
+ const int NETWORK_VALIDATION_PROBE_PRIVDNS = 64;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkMonitorCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkMonitorCallbacks.aidl
new file mode 100644
index 0000000..b7ddad9
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkMonitorCallbacks.aidl
@@ -0,0 +1,30 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkMonitorCallbacks {
+ oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor) = 0;
+ oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl) = 1;
+ oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config) = 2;
+ oneway void showProvisioningNotification(String action, String packageName) = 3;
+ oneway void hideProvisioningNotification() = 4;
+ oneway void notifyProbeStatusChanged(int probesCompleted, int probesSucceeded) = 5;
+ oneway void notifyNetworkTestedWithExtras(in android.net.NetworkTestResultParcelable result) = 6;
+ oneway void notifyDataStallSuspected(in android.net.DataStallReportParcelable report) = 7;
+ oneway void notifyCaptivePortalDataChanged(in android.net.CaptivePortalData data) = 8;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkStackConnector.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkStackConnector.aidl
new file mode 100644
index 0000000..17a65cf
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkStackConnector {
+ oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
+ oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
+ oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
+ oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkStackStatusCallback.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkStackStatusCallback.aidl
new file mode 100644
index 0000000..ec16def
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/INetworkStackStatusCallback.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+/* @hide */
+interface INetworkStackStatusCallback {
+ oneway void onStatusAvailable(int statusCode);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/InformationElementParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/InformationElementParcelable.aidl
new file mode 100644
index 0000000..c882bf4
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/InformationElementParcelable.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable InformationElementParcelable {
+ int id;
+ byte[] payload;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/InitialConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/InitialConfigurationParcelable.aidl
new file mode 100644
index 0000000..c91d7a2
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/InitialConfigurationParcelable.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable InitialConfigurationParcelable {
+ android.net.LinkAddress[] ipAddresses;
+ android.net.IpPrefix[] directlyConnectedRoutes;
+ String[] dnsServers;
+ String gateway;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/Layer2InformationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/Layer2InformationParcelable.aidl
new file mode 100644
index 0000000..dca5138
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/Layer2InformationParcelable.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable Layer2InformationParcelable {
+ String l2Key;
+ String cluster;
+ android.net.MacAddress bssid;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/Layer2PacketParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/Layer2PacketParcelable.aidl
new file mode 100644
index 0000000..2e0955f
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/Layer2PacketParcelable.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable Layer2PacketParcelable {
+ android.net.MacAddress dstMacAddress;
+ byte[] payload;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/NattKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/NattKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..aa09c3d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable NattKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/NetworkTestResultParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/NetworkTestResultParcelable.aidl
new file mode 100644
index 0000000..f31a669
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/NetworkTestResultParcelable.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable NetworkTestResultParcelable {
+ long timestampMillis;
+ int result;
+ int probesSucceeded;
+ int probesAttempted;
+ String redirectUrl;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/PrivateDnsConfigParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/PrivateDnsConfigParcel.aidl
new file mode 100644
index 0000000..cada4d3
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/PrivateDnsConfigParcel.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable PrivateDnsConfigParcel {
+ String hostname;
+ String[] ips;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ProvisioningConfigurationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ProvisioningConfigurationParcelable.aidl
new file mode 100644
index 0000000..b8dfb91
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ProvisioningConfigurationParcelable.aidl
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable ProvisioningConfigurationParcelable {
+ boolean enableIPv4;
+ boolean enableIPv6;
+ boolean usingMultinetworkPolicyTracker;
+ boolean usingIpReachabilityMonitor;
+ int requestedPreDhcpActionMs;
+ android.net.InitialConfigurationParcelable initialConfig;
+ android.net.StaticIpConfiguration staticIpConfig;
+ android.net.apf.ApfCapabilities apfCapabilities;
+ int provisioningTimeoutMs;
+ int ipv6AddrGenMode;
+ android.net.Network network;
+ String displayName;
+ boolean enablePreconnection;
+ @nullable android.net.ScanResultInfoParcelable scanResultInfo;
+ @nullable android.net.Layer2InformationParcelable layer2Info;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ScanResultInfoParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ScanResultInfoParcelable.aidl
new file mode 100644
index 0000000..f7ac167
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ScanResultInfoParcelable.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable ScanResultInfoParcelable {
+ String ssid;
+ String bssid;
+ android.net.InformationElementParcelable[] informationElements;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/TcpKeepalivePacketDataParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/TcpKeepalivePacketDataParcelable.aidl
new file mode 100644
index 0000000..c50f541
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -0,0 +1,30 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net;
+parcelable TcpKeepalivePacketDataParcelable {
+ byte[] srcAddress;
+ int srcPort;
+ byte[] dstAddress;
+ int dstPort;
+ int seq;
+ int ack;
+ int rcvWnd;
+ int rcvWndScale;
+ int tos;
+ int ttl;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/DhcpLeaseParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/DhcpLeaseParcelable.aidl
new file mode 100644
index 0000000..adbd57d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/DhcpLeaseParcelable.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+parcelable DhcpLeaseParcelable {
+ byte[] clientId;
+ byte[] hwAddr;
+ int netAddr;
+ int prefixLength;
+ long expTime;
+ String hostname;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/DhcpServingParamsParcel.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/DhcpServingParamsParcel.aidl
new file mode 100644
index 0000000..d66ca9d
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -0,0 +1,30 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+parcelable DhcpServingParamsParcel {
+ int serverAddr;
+ int serverAddrPrefixLength;
+ int[] defaultRouters;
+ int[] dnsServers;
+ int[] excludedAddrs;
+ long dhcpLeaseTimeSecs;
+ int linkMtu;
+ boolean metered;
+ int singleClientAddr = 0;
+ boolean changePrefixOnDecline = false;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpEventCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpEventCallbacks.aidl
new file mode 100644
index 0000000..dfcaf98
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpEventCallbacks.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+interface IDhcpEventCallbacks {
+ oneway void onLeasesChanged(in List<android.net.dhcp.DhcpLeaseParcelable> newLeases);
+ oneway void onNewPrefixRequest(in android.net.IpPrefix currentPrefix);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpServer.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpServer.aidl
new file mode 100644
index 0000000..ef936cc
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpServer.aidl
@@ -0,0 +1,29 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+/* @hide */
+interface IDhcpServer {
+ oneway void start(in android.net.INetworkStackStatusCallback cb) = 0;
+ oneway void startWithCallbacks(in android.net.INetworkStackStatusCallback statusCb, in android.net.dhcp.IDhcpEventCallbacks eventCb) = 3;
+ oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb) = 1;
+ oneway void stop(in android.net.INetworkStackStatusCallback cb) = 2;
+ const int STATUS_UNKNOWN = 0;
+ const int STATUS_SUCCESS = 1;
+ const int STATUS_INVALID_ARGUMENT = 2;
+ const int STATUS_UNKNOWN_ERROR = 3;
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpServerCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpServerCallbacks.aidl
new file mode 100644
index 0000000..63b89ad
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.dhcp;
+/* @hide */
+interface IDhcpServerCallbacks {
+ oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ip/IIpClient.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ip/IIpClient.aidl
new file mode 100644
index 0000000..9245954
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ip/IIpClient.aidl
@@ -0,0 +1,36 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ip;
+/* @hide */
+interface IIpClient {
+ oneway void completedPreDhcpAction();
+ oneway void confirmConfiguration();
+ oneway void readPacketFilterComplete(in byte[] data);
+ oneway void shutdown();
+ oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
+ oneway void stop();
+ oneway void setTcpBufferSizes(in String tcpBufferSizes);
+ oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
+ oneway void setMulticastFilter(boolean enabled);
+ oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
+ oneway void removeKeepalivePacketFilter(int slot);
+ oneway void setL2KeyAndGroupHint(in String l2Key, in String cluster);
+ oneway void addNattKeepalivePacketFilter(int slot, in android.net.NattKeepalivePacketDataParcelable pkt);
+ oneway void notifyPreconnectionComplete(boolean success);
+ oneway void updateLayer2Information(in android.net.Layer2InformationParcelable info);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ip/IIpClientCallbacks.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ip/IIpClientCallbacks.aidl
new file mode 100644
index 0000000..9aabb1f
--- /dev/null
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/7/android/net/ip/IIpClientCallbacks.aidl
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.net.ip;
+/* @hide */
+interface IIpClientCallbacks {
+ oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
+ oneway void onPreDhcpAction();
+ oneway void onPostDhcpAction();
+ oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
+ oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
+ oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
+ oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
+ oneway void onReachabilityLost(in String logMsg);
+ oneway void onQuit();
+ oneway void installPacketFilter(in byte[] filter);
+ oneway void startReadPacketFilter();
+ oneway void setFallbackMulticastFilter(boolean enabled);
+ oneway void setNeighborDiscoveryOffload(boolean enable);
+ oneway void onPreconnectionStart(in List<android.net.Layer2PacketParcelable> packets);
+}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/Layer2InformationParcelable.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/Layer2InformationParcelable.aidl
index c733188..dca5138 100644
--- a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/Layer2InformationParcelable.aidl
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/Layer2InformationParcelable.aidl
@@ -18,6 +18,6 @@
package android.net;
parcelable Layer2InformationParcelable {
String l2Key;
- String groupHint;
+ String cluster;
android.net.MacAddress bssid;
}
diff --git a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/ip/IIpClient.aidl b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/ip/IIpClient.aidl
index 6c2d86b..9245954 100644
--- a/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/ip/IIpClient.aidl
+++ b/common/networkstackclient/aidl_api/networkstack-aidl-interfaces/current/android/net/ip/IIpClient.aidl
@@ -29,7 +29,7 @@
oneway void setMulticastFilter(boolean enabled);
oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
oneway void removeKeepalivePacketFilter(int slot);
- oneway void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
+ oneway void setL2KeyAndGroupHint(in String l2Key, in String cluster);
oneway void addNattKeepalivePacketFilter(int slot, in android.net.NattKeepalivePacketDataParcelable pkt);
oneway void notifyPreconnectionComplete(boolean success);
oneway void updateLayer2Information(in android.net.Layer2InformationParcelable info);
diff --git a/common/networkstackclient/src/android/net/IIpMemoryStore.aidl b/common/networkstackclient/src/android/net/IIpMemoryStore.aidl
index add221a..3bb58bf 100644
--- a/common/networkstackclient/src/android/net/IIpMemoryStore.aidl
+++ b/common/networkstackclient/src/android/net/IIpMemoryStore.aidl
@@ -22,6 +22,7 @@
import android.net.ipmemorystore.IOnL2KeyResponseListener;
import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
+import android.net.ipmemorystore.IOnStatusAndCountListener;
import android.net.ipmemorystore.IOnStatusListener;
/** {@hide} */
@@ -39,8 +40,7 @@
* @param attributes The attributes for this network.
* @param listener A listener that will be invoked to inform of the completion of this call,
* or null if the client is not interested in learning about success/failure.
- * @return (through the listener) The L2 key. This is useful if the L2 key was not specified.
- * If the call failed, the L2 key will be null.
+ * @return (through the listener) A status to indicate success or failure.
*/
void storeNetworkAttributes(String l2Key, in NetworkAttributesParcelable attributes,
IOnStatusListener listener);
@@ -115,4 +115,41 @@
* Delete all data because a factory reset operation is in progress.
*/
void factoryReset();
+
+ /**
+ * Delete a single entry.
+ *
+ * @param l2key The L2 key of the entry to delete.
+ * @param needWipe Whether the data must be wiped from disk immediately. This makes the
+ * operation vastly more expensive as the database files will have to be copied
+ * and created again from the old files (see sqlite3 VACUUM operation for
+ * details) and makes no functional difference; only pass true if security or
+ * privacy demands this data must be removed from disk immediately.
+ * Note that this can fail for storage reasons. The passed listener will then
+ * receive an appropriate error status with the number of deleted rows.
+ * @param listener A listener that will be invoked to inform of the completion of this call,
+ * or null if the client is not interested in learning about success/failure.
+ * @return (through the listener) A status to indicate success and the number of deleted records
+ */
+ void delete(String l2Key, boolean needWipe, IOnStatusAndCountListener listener);
+
+ /**
+ * Delete all entries in a cluster.
+ *
+ * This method will delete all entries in the memory store that have the cluster attribute
+ * passed as an argument.
+ *
+ * @param cluster The cluster to delete.
+ * @param needWipe Whether the data must be wiped from disk immediately. This makes the
+ * operation vastly more expensive as the database files will have to be copied
+ * and created again from the old files (see sqlite3 VACUUM operation for
+ * details) and makes no functional difference; only pass true if security or
+ * privacy demands this data must be removed from disk immediately.
+ * Note that this can fail for storage reasons. The passed listener will then
+ * receive an appropriate error status with the number of deleted rows.
+ * @param listener A listener that will be invoked to inform of the completion of this call,
+ * or null if the client is not interested in learning about success/failure.
+ * @return (through the listener) A status to indicate success and the number of deleted records
+ */
+ void deleteCluster(String cluster, boolean needWipe, IOnStatusAndCountListener listener);
}
diff --git a/common/networkstackclient/src/android/net/IpMemoryStoreClient.java b/common/networkstackclient/src/android/net/IpMemoryStoreClient.java
index 014b528..f269f9c 100644
--- a/common/networkstackclient/src/android/net/IpMemoryStoreClient.java
+++ b/common/networkstackclient/src/android/net/IpMemoryStoreClient.java
@@ -22,6 +22,7 @@
import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.OnBlobRetrievedListener;
+import android.net.ipmemorystore.OnDeleteStatusListener;
import android.net.ipmemorystore.OnL2KeyResponseListener;
import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener;
import android.net.ipmemorystore.OnSameL3NetworkResponseListener;
@@ -214,6 +215,64 @@
}
/**
+ * Delete a single entry.
+ *
+ * @param l2Key The L2 key of the entry to delete.
+ * @param needWipe Whether the data must be wiped from disk immediately. This makes the
+ * operation vastly more expensive as the database files will have to be copied
+ * and created again from the old files (see sqlite3 VACUUM operation for
+ * details) and makes no functional difference; only pass true if security or
+ * privacy demands this data must be removed from disk immediately.
+ * Note that this can fail for storage reasons. The passed listener will then
+ * receive an appropriate error status with the number of deleted rows.
+ * @param listener A listener that will be invoked to inform of the completion of this call,
+ * or null if the client is not interested in learning about success/failure.
+ * returns (through the listener) A status to indicate success and the number of deleted records
+ */
+ public void delete(@NonNull final String l2Key, final boolean needWipe,
+ @Nullable final OnDeleteStatusListener listener) {
+ try {
+ runWhenServiceReady(service -> ignoringRemoteException(() ->
+ service.delete(l2Key, needWipe, OnDeleteStatusListener.toAIDL(listener))));
+ } catch (ExecutionException m) {
+ ignoringRemoteException("Error deleting from the memory store",
+ () -> listener.onComplete(new Status(Status.ERROR_UNKNOWN),
+ 0 /* deletedRecords */));
+ }
+ }
+
+ /**
+ * Delete all entries in a cluster.
+ *
+ * This method will delete all entries in the memory store that have the cluster attribute
+ * passed as an argument.
+ *
+ * @param cluster The cluster to delete.
+ * @param needWipe Whether the data must be wiped from disk immediately. This makes the
+ * operation vastly more expensive as the database files will have to be copied
+ * and created again from the old files (see sqlite3 VACUUM operation for
+ * details) and makes no functional difference; only pass true if security or
+ * privacy demands this data must be removed from disk immediately.
+ * Note that this can fail for storage reasons. The passed listener will then
+ * receive an appropriate error status with the number of deleted rows.
+ * @param listener A listener that will be invoked to inform of the completion of this call,
+ * or null if the client is not interested in learning about success/failure.
+ * returns (through the listener) A status to indicate success and the number of deleted records
+ */
+ public void deleteCluster(@NonNull final String cluster, final boolean needWipe,
+ @Nullable final OnDeleteStatusListener listener) {
+ try {
+ runWhenServiceReady(service -> ignoringRemoteException(
+ () -> service.deleteCluster(cluster, needWipe,
+ OnDeleteStatusListener.toAIDL(listener))));
+ } catch (ExecutionException m) {
+ ignoringRemoteException("Error deleting from the memory store",
+ () -> listener.onComplete(new Status(Status.ERROR_UNKNOWN),
+ 0 /* deletedRecords */));
+ }
+ }
+
+ /**
* Wipe the data in the database upon network factory reset.
*/
public void factoryReset() {
diff --git a/common/networkstackclient/src/android/net/Layer2InformationParcelable.aidl b/common/networkstackclient/src/android/net/Layer2InformationParcelable.aidl
index 496d291..a8eda0d 100644
--- a/common/networkstackclient/src/android/net/Layer2InformationParcelable.aidl
+++ b/common/networkstackclient/src/android/net/Layer2InformationParcelable.aidl
@@ -20,6 +20,6 @@
parcelable Layer2InformationParcelable {
String l2Key;
- String groupHint;
+ String cluster;
MacAddress bssid;
}
diff --git a/common/networkstackclient/src/android/net/ip/IIpClient.aidl b/common/networkstackclient/src/android/net/ip/IIpClient.aidl
index 0027949..029bdb3 100644
--- a/common/networkstackclient/src/android/net/ip/IIpClient.aidl
+++ b/common/networkstackclient/src/android/net/ip/IIpClient.aidl
@@ -34,7 +34,8 @@
void setMulticastFilter(boolean enabled);
void addKeepalivePacketFilter(int slot, in TcpKeepalivePacketDataParcelable pkt);
void removeKeepalivePacketFilter(int slot);
- void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
+ /* Group hint is the old name for cluster */
+ void setL2KeyAndGroupHint(in String l2Key, in String cluster);
void addNattKeepalivePacketFilter(int slot, in NattKeepalivePacketDataParcelable pkt);
void notifyPreconnectionComplete(boolean success);
void updateLayer2Information(in Layer2InformationParcelable info);
diff --git a/common/networkstackclient/src/android/net/ipmemorystore/IOnStatusAndCountListener.aidl b/common/networkstackclient/src/android/net/ipmemorystore/IOnStatusAndCountListener.aidl
new file mode 100644
index 0000000..c19b5c1
--- /dev/null
+++ b/common/networkstackclient/src/android/net/ipmemorystore/IOnStatusAndCountListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.net.ipmemorystore.StatusParcelable;
+
+/** {@hide} */
+oneway interface IOnStatusAndCountListener {
+ /**
+ * The operation has completed with the specified status, and supplied the passed count
+ * as call-specific additional data.
+ */
+ void onComplete(in StatusParcelable status, int count);
+}
diff --git a/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java
index 818515a..2e444fe 100644
--- a/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java
+++ b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java
@@ -67,11 +67,11 @@
// same L3 network".
private static final float WEIGHT_ASSIGNEDV4ADDREXPIRY = 0.0f;
- // Optionally supplied by the client if it has an opinion on L3 network. For example, this
- // could be a hash of the SSID + security type on WiFi.
+ // Optionally supplied by the client to signify belonging to a notion of a group owned by
+ // the client. For example, this could be a hash of the SSID on WiFi.
@Nullable
- public final String groupHint;
- private static final float WEIGHT_GROUPHINT = 300.0f;
+ public final String cluster;
+ private static final float WEIGHT_CLUSTER = 300.0f;
// The list of DNS server addresses.
@Nullable
@@ -89,7 +89,7 @@
@VisibleForTesting
public static final float TOTAL_WEIGHT = WEIGHT_ASSIGNEDV4ADDR
+ WEIGHT_ASSIGNEDV4ADDREXPIRY
- + WEIGHT_GROUPHINT
+ + WEIGHT_CLUSTER
+ WEIGHT_DNSADDRESSES
+ WEIGHT_MTU;
@@ -98,7 +98,7 @@
public NetworkAttributes(
@Nullable final Inet4Address assignedV4Address,
@Nullable final Long assignedV4AddressExpiry,
- @Nullable final String groupHint,
+ @Nullable final String cluster,
@Nullable final List<InetAddress> dnsAddresses,
@Nullable final Integer mtu) {
if (mtu != null && mtu < 0) throw new IllegalArgumentException("MTU can't be negative");
@@ -107,7 +107,7 @@
}
this.assignedV4Address = assignedV4Address;
this.assignedV4AddressExpiry = assignedV4AddressExpiry;
- this.groupHint = groupHint;
+ this.cluster = cluster;
this.dnsAddresses = null == dnsAddresses ? null :
Collections.unmodifiableList(new ArrayList<>(dnsAddresses));
this.mtu = mtu;
@@ -120,7 +120,7 @@
this((Inet4Address) getByAddressOrNull(parcelable.assignedV4Address),
parcelable.assignedV4AddressExpiry > 0
? parcelable.assignedV4AddressExpiry : null,
- parcelable.groupHint,
+ parcelable.cluster,
blobArrayToInetAddressList(parcelable.dnsAddresses),
parcelable.mtu >= 0 ? parcelable.mtu : null);
}
@@ -168,7 +168,7 @@
(null == assignedV4Address) ? null : assignedV4Address.getAddress();
parcelable.assignedV4AddressExpiry =
(null == assignedV4AddressExpiry) ? 0 : assignedV4AddressExpiry;
- parcelable.groupHint = groupHint;
+ parcelable.cluster = cluster;
parcelable.dnsAddresses = inetAddressListToBlobArray(dnsAddresses);
parcelable.mtu = (null == mtu) ? -1 : mtu;
return parcelable;
@@ -188,7 +188,7 @@
samenessContribution(WEIGHT_ASSIGNEDV4ADDR, assignedV4Address, o.assignedV4Address)
+ samenessContribution(WEIGHT_ASSIGNEDV4ADDREXPIRY, assignedV4AddressExpiry,
o.assignedV4AddressExpiry)
- + samenessContribution(WEIGHT_GROUPHINT, groupHint, o.groupHint)
+ + samenessContribution(WEIGHT_CLUSTER, cluster, o.cluster)
+ samenessContribution(WEIGHT_DNSADDRESSES, dnsAddresses, o.dnsAddresses)
+ samenessContribution(WEIGHT_MTU, mtu, o.mtu);
// The minimum is 0, the max is TOTAL_WEIGHT and should be represented by 1.0, and
@@ -211,13 +211,29 @@
@Nullable
private Long mAssignedAddressExpiry;
@Nullable
- private String mGroupHint;
+ private String mCluster;
@Nullable
private List<InetAddress> mDnsAddresses;
@Nullable
private Integer mMtu;
/**
+ * Constructs a new Builder.
+ */
+ public Builder() {}
+
+ /**
+ * Constructs a Builder from the passed NetworkAttributes.
+ */
+ public Builder(@NonNull final NetworkAttributes attributes) {
+ mAssignedAddress = attributes.assignedV4Address;
+ mAssignedAddressExpiry = attributes.assignedV4AddressExpiry;
+ mCluster = attributes.cluster;
+ mDnsAddresses = new ArrayList<>(attributes.dnsAddresses);
+ mMtu = attributes.mtu;
+ }
+
+ /**
* Set the assigned address.
* @param assignedV4Address The assigned address.
* @return This builder.
@@ -244,12 +260,12 @@
}
/**
- * Set the group hint.
- * @param groupHint The group hint.
+ * Set the cluster.
+ * @param cluster The cluster.
* @return This builder.
*/
- public Builder setGroupHint(@Nullable final String groupHint) {
- mGroupHint = groupHint;
+ public Builder setCluster(@Nullable final String cluster) {
+ mCluster = cluster;
return this;
}
@@ -287,14 +303,14 @@
*/
public NetworkAttributes build() {
return new NetworkAttributes(mAssignedAddress, mAssignedAddressExpiry,
- mGroupHint, mDnsAddresses, mMtu);
+ mCluster, mDnsAddresses, mMtu);
}
}
/** @hide */
public boolean isEmpty() {
return (null == assignedV4Address) && (null == assignedV4AddressExpiry)
- && (null == groupHint) && (null == dnsAddresses) && (null == mtu);
+ && (null == cluster) && (null == dnsAddresses) && (null == mtu);
}
@Override
@@ -303,7 +319,7 @@
final NetworkAttributes other = (NetworkAttributes) o;
return Objects.equals(assignedV4Address, other.assignedV4Address)
&& Objects.equals(assignedV4AddressExpiry, other.assignedV4AddressExpiry)
- && Objects.equals(groupHint, other.groupHint)
+ && Objects.equals(cluster, other.cluster)
&& Objects.equals(dnsAddresses, other.dnsAddresses)
&& Objects.equals(mtu, other.mtu);
}
@@ -311,7 +327,7 @@
@Override
public int hashCode() {
return Objects.hash(assignedV4Address, assignedV4AddressExpiry,
- groupHint, dnsAddresses, mtu);
+ cluster, dnsAddresses, mtu);
}
/** Pretty print */
@@ -334,11 +350,11 @@
nullFields.add("assignedV4AddressExpiry");
}
- if (null != groupHint) {
- resultJoiner.add("groupHint :");
- resultJoiner.add(groupHint);
+ if (null != cluster) {
+ resultJoiner.add("cluster :");
+ resultJoiner.add(cluster);
} else {
- nullFields.add("groupHint");
+ nullFields.add("cluster");
}
if (null != dnsAddresses) {
diff --git a/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
index 997eb2b..b710427 100644
--- a/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -31,7 +31,7 @@
parcelable NetworkAttributesParcelable {
byte[] assignedV4Address;
long assignedV4AddressExpiry;
- String groupHint;
+ String cluster;
Blob[] dnsAddresses;
int mtu;
}
diff --git a/common/networkstackclient/src/android/net/ipmemorystore/OnDeleteStatusListener.java b/common/networkstackclient/src/android/net/ipmemorystore/OnDeleteStatusListener.java
new file mode 100644
index 0000000..7138877
--- /dev/null
+++ b/common/networkstackclient/src/android/net/ipmemorystore/OnDeleteStatusListener.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * A listener for the IpMemoryStore to return a status to a client.
+ * @hide
+ */
+public interface OnDeleteStatusListener {
+ /**
+ * The operation has completed with the specified status, and deleted the specified
+ * number of records. The operation can fail with a non-zero count of deleted rows as
+ * wipe requests may fail for lack of storage. See the documentation of each deletion
+ * method for details.
+ */
+ void onComplete(Status status, int deletedRecords);
+
+ /** Converts this OnDeleteStatusListener to a parcelable object */
+ @NonNull
+ static IOnStatusAndCountListener toAIDL(@Nullable final OnDeleteStatusListener listener) {
+ return new IOnStatusAndCountListener.Stub() {
+ @Override
+ public void onComplete(final StatusParcelable statusParcelable, int deletedRecords) {
+ if (null != listener) {
+ listener.onComplete(new Status(statusParcelable), deletedRecords);
+ }
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return this.HASH;
+ }
+ };
+ }
+}
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index f3dcdc8..018d6ab 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -64,7 +64,6 @@
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;
-import android.util.Patterns;
import android.util.SparseArray;
import androidx.annotation.NonNull;
@@ -86,6 +85,8 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -381,7 +382,7 @@
private static final int EVENT_READ_PACKET_FILTER_COMPLETE = 12;
private static final int CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF = 13;
private static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF = 14;
- private static final int CMD_UPDATE_L2KEY_GROUPHINT = 15;
+ private static final int CMD_UPDATE_L2KEY_CLUSTER = 15;
private static final int CMD_COMPLETE_PRECONNECTION = 16;
private static final int CMD_UPDATE_L2INFORMATION = 17;
@@ -477,7 +478,7 @@
private ProxyInfo mHttpProxy;
private ApfFilter mApfFilter;
private String mL2Key; // The L2 key for this network, for writing into the memory store
- private String mGroupHint; // The group hint for this network, for writing into the memory store
+ private String mCluster; // The cluster for this network, for writing into the memory store
private boolean mMulticastFiltering;
private long mStartTimeMillis;
private MacAddress mCurrentBssid;
@@ -686,9 +687,9 @@
IpClient.this.stop();
}
@Override
- public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
+ public void setL2KeyAndGroupHint(String l2Key, String cluster) {
enforceNetworkStackCallingPermission();
- IpClient.this.setL2KeyAndGroupHint(l2Key, groupHint);
+ IpClient.this.setL2KeyAndCluster(l2Key, cluster);
}
@Override
public void setTcpBufferSizes(String tcpBufferSizes) {
@@ -805,7 +806,7 @@
if (req.mLayer2Info != null) {
mL2Key = req.mLayer2Info.mL2Key;
- mGroupHint = req.mLayer2Info.mGroupHint;
+ mCluster = req.mLayer2Info.mCluster;
}
sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req));
}
@@ -853,14 +854,14 @@
}
/**
- * Set the L2 key and group hint for storing info into the memory store.
+ * Set the L2 key and cluster for storing info into the memory store.
*
* This method is only supported on Q devices. For R or above releases,
* caller should call #updateLayer2Information() instead.
*/
- public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
+ public void setL2KeyAndCluster(String l2Key, String cluster) {
if (!ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)) {
- sendMessage(CMD_UPDATE_L2KEY_GROUPHINT, new Pair<>(l2Key, groupHint));
+ sendMessage(CMD_UPDATE_L2KEY_CLUSTER, new Pair<>(l2Key, cluster));
}
}
@@ -917,7 +918,7 @@
}
/**
- * Update the network bssid, L2Key and GroupHint on L2 roaming happened.
+ * Update the network bssid, L2Key and cluster on L2 roaming happened.
*/
public void updateLayer2Information(@NonNull Layer2InformationParcelable info) {
sendMessage(CMD_UPDATE_L2INFORMATION, info);
@@ -1263,9 +1264,9 @@
}
final String capportUrl = mDhcpResults.captivePortalApiUrl;
- // Uri.parse does no syntax check; do a simple regex check to eliminate garbage.
+ // Uri.parse does no syntax check; do a simple check to eliminate garbage.
// If the URL is still incorrect data fetching will fail later, which is fine.
- if (capportUrl != null && Patterns.WEB_URL.matcher(capportUrl).matches()) {
+ if (isParseableUrl(capportUrl)) {
NetworkInformationShimImpl.newInstance()
.setCaptivePortalApiUrl(newLp, Uri.parse(capportUrl));
}
@@ -1303,6 +1304,19 @@
return newLp;
}
+ private static boolean isParseableUrl(String url) {
+ // Verify that a URL has a reasonable format that can be parsed as per the URL constructor.
+ // This does not use Patterns.WEB_URL as that pattern excludes URLs without TLDs, such as on
+ // localhost.
+ if (url == null) return false;
+ try {
+ new URL(url);
+ return true;
+ } catch (MalformedURLException e) {
+ return false;
+ }
+ }
+
private static void addAllReachableDnsServers(
LinkProperties lp, Iterable<InetAddress> dnses) {
// TODO: Investigate deleting this reachability check. We should be
@@ -1545,7 +1559,7 @@
private void handleUpdateL2Information(@NonNull Layer2InformationParcelable info) {
mL2Key = info.l2Key;
- mGroupHint = info.groupHint;
+ mCluster = info.cluster;
if (info.bssid == null || mCurrentBssid == null) {
Log.wtf(mTag, "bssid in the parcelable or current tracked bssid should be non-null");
@@ -1619,10 +1633,10 @@
handleLinkPropertiesUpdate(NO_CALLBACKS);
break;
- case CMD_UPDATE_L2KEY_GROUPHINT: {
+ case CMD_UPDATE_L2KEY_CLUSTER: {
final Pair<String, String> args = (Pair<String, String>) msg.obj;
mL2Key = args.first;
- mGroupHint = args.second;
+ mCluster = args.second;
break;
}
@@ -1824,10 +1838,10 @@
transitionTo(mStoppingState);
break;
- case CMD_UPDATE_L2KEY_GROUPHINT: {
+ case CMD_UPDATE_L2KEY_CLUSTER: {
final Pair<String, String> args = (Pair<String, String>) msg.obj;
mL2Key = args.first;
- mGroupHint = args.second;
+ mCluster = args.second;
// TODO : attributes should be saved to the memory store with
// these new values if they differ from the previous ones.
// If the state machine is in pure StartedState, then the values to input
diff --git a/src/com/android/server/connectivity/NetworkMonitor.java b/src/com/android/server/connectivity/NetworkMonitor.java
index 8a1b0c7..bee3634 100755
--- a/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/src/com/android/server/connectivity/NetworkMonitor.java
@@ -83,6 +83,7 @@
import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_DNS_EVENTS;
import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_TCP_METRICS;
+import static com.android.networkstack.apishim.ConstantsShim.TRANSPORT_TEST;
import static com.android.networkstack.util.DnsUtils.PRIVATE_DNS_PROBE_HOST_SUFFIX;
import static com.android.networkstack.util.DnsUtils.TYPE_ADDRCONFIG;
@@ -387,7 +388,8 @@
private static final int CMD_BANDWIDTH_CHECK_TIMEOUT = 24;
// Start mReevaluateDelayMs at this value and double.
- private static final int INITIAL_REEVALUATE_DELAY_MS = 1000;
+ @VisibleForTesting
+ static final int INITIAL_REEVALUATE_DELAY_MS = 1000;
private static final int MAX_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
// Default timeout of evaluating network bandwidth.
private static final int DEFAULT_EVALUATING_BANDWIDTH_TIMEOUT_MS = 10_000;
@@ -1434,8 +1436,9 @@
}
final int token = ++mProbeToken;
+ final EvaluationThreadDeps deps = new EvaluationThreadDeps(mNetworkCapabilities);
mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0,
- isCaptivePortal())));
+ isCaptivePortal(deps))));
mThread.start();
}
@@ -2147,8 +2150,25 @@
return mCaptivePortalFallbackSpecs[idx];
}
- @VisibleForTesting
- protected CaptivePortalProbeResult isCaptivePortal() {
+ /**
+ * Parameters that can be accessed by the evaluation thread in a thread-safe way.
+ *
+ * Parameters such as LinkProperties and NetworkCapabilities cannot be accessed by the
+ * evaluation thread directly, as they are managed in the state machine thread and not
+ * synchronized. This class provides a copy of the required data that is not modified and can be
+ * used safely by the evaluation thread.
+ */
+ private static class EvaluationThreadDeps {
+ // TODO: add parameters that are accessed in a non-thread-safe way from the evaluation
+ // thread (read from LinkProperties, NetworkCapabilities, useHttps, validationStage)
+ private final boolean mIsTestNetwork;
+
+ EvaluationThreadDeps(NetworkCapabilities nc) {
+ this.mIsTestNetwork = nc.hasTransport(TRANSPORT_TEST);
+ }
+ }
+
+ private CaptivePortalProbeResult isCaptivePortal(EvaluationThreadDeps deps) {
if (!mIsCaptivePortalCheckEnabled) {
validationLog("Validation disabled.");
return CaptivePortalProbeResult.success(CaptivePortalProbeResult.PROBE_UNKNOWN);
@@ -2196,11 +2216,11 @@
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
} else if (mUseHttps && httpsUrls.length == 1 && httpUrls.length == 1) {
// Probe results are reported inside sendHttpAndHttpsParallelWithFallbackProbes.
- result = sendHttpAndHttpsParallelWithFallbackProbes(
- proxyInfo, httpsUrls[0], httpUrls[0]);
+ result = sendHttpAndHttpsParallelWithFallbackProbes(deps, proxyInfo,
+ httpsUrls[0], httpUrls[0]);
} else if (mUseHttps) {
// Support result aggregation from multiple Urls.
- result = sendMultiParallelHttpAndHttpsProbes(proxyInfo, httpsUrls, httpUrls);
+ result = sendMultiParallelHttpAndHttpsProbes(deps, proxyInfo, httpsUrls, httpUrls);
} else {
result = sendDnsAndHttpProbes(proxyInfo, httpUrls[0], ValidationProbeEvent.PROBE_HTTP);
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
@@ -2482,12 +2502,12 @@
private final CountDownLatch mLatch;
private final Probe mProbe;
- ProbeThread(CountDownLatch latch, ProxyInfo proxy, URL url, int probeType,
- Uri captivePortalApiUrl) {
+ ProbeThread(CountDownLatch latch, EvaluationThreadDeps deps, ProxyInfo proxy, URL url,
+ int probeType, Uri captivePortalApiUrl) {
mLatch = latch;
mProbe = (probeType == ValidationProbeEvent.PROBE_HTTPS)
- ? new HttpsProbe(proxy, url, captivePortalApiUrl)
- : new HttpProbe(proxy, url, captivePortalApiUrl);
+ ? new HttpsProbe(deps, proxy, url, captivePortalApiUrl)
+ : new HttpProbe(deps, proxy, url, captivePortalApiUrl);
mResult = CaptivePortalProbeResult.failed(probeType);
}
@@ -2512,11 +2532,14 @@
}
private abstract static class Probe {
+ protected final EvaluationThreadDeps mDeps;
protected final ProxyInfo mProxy;
protected final URL mUrl;
protected final Uri mCaptivePortalApiUrl;
- protected Probe(ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
+ protected Probe(EvaluationThreadDeps deps, ProxyInfo proxy, URL url,
+ Uri captivePortalApiUrl) {
+ mDeps = deps;
mProxy = proxy;
mUrl = url;
mCaptivePortalApiUrl = captivePortalApiUrl;
@@ -2526,8 +2549,8 @@
}
final class HttpsProbe extends Probe {
- HttpsProbe(ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
- super(proxy, url, captivePortalApiUrl);
+ HttpsProbe(EvaluationThreadDeps deps, ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
+ super(deps, proxy, url, captivePortalApiUrl);
}
@Override
@@ -2537,8 +2560,8 @@
}
final class HttpProbe extends Probe {
- HttpProbe(ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
- super(proxy, url, captivePortalApiUrl);
+ HttpProbe(EvaluationThreadDeps deps, ProxyInfo proxy, URL url, Uri captivePortalApiUrl) {
+ super(deps, proxy, url, captivePortalApiUrl);
}
private CaptivePortalDataShim tryCapportApiProbe() {
@@ -2548,7 +2571,12 @@
final String apiContent;
try {
final URL url = new URL(mCaptivePortalApiUrl.toString());
- if (!"https".equals(url.getProtocol())) {
+ // Protocol must be HTTPS
+ // (as per https://www.ietf.org/id/draft-ietf-capport-api-07.txt, #4).
+ // Only allow HTTP on localhost, for testing.
+ final boolean isTestLocalhostHttp = mDeps.mIsTestNetwork
+ && "localhost".equals(url.getHost()) && "http".equals(url.getProtocol());
+ if (!"https".equals(url.getProtocol()) && !isTestLocalhostHttp) {
validationLog("Invalid captive portal API protocol: " + url.getProtocol());
return null;
}
@@ -2631,8 +2659,9 @@
&& captivePortalApiUrl == null);
}
- private CaptivePortalProbeResult sendMultiParallelHttpAndHttpsProbes(@NonNull ProxyInfo proxy,
- @NonNull URL[] httpsUrls, @NonNull URL[] httpUrls) {
+ private CaptivePortalProbeResult sendMultiParallelHttpAndHttpsProbes(
+ @NonNull EvaluationThreadDeps deps, @Nullable ProxyInfo proxy, @NonNull URL[] httpsUrls,
+ @NonNull URL[] httpUrls) {
// If multiple URLs are required to ensure the correctness of validation, send parallel
// probes to explore the result in separate probe threads and aggregate those results into
// one as the final result for either HTTP or HTTPS.
@@ -2657,13 +2686,13 @@
// TODO: Have the capport probe as a different probe for cleanliness.
final URL urlMaybeWithCapport = httpUrls[0];
for (final URL url : httpUrls) {
- futures.add(ecs.submit(() -> new HttpProbe(proxy, url,
+ futures.add(ecs.submit(() -> new HttpProbe(deps, proxy, url,
url.equals(urlMaybeWithCapport) ? capportApiUrl : null).sendProbe()));
}
for (final URL url : httpsUrls) {
- futures.add(
- ecs.submit(() -> new HttpsProbe(proxy, url, capportApiUrl).sendProbe()));
+ futures.add(ecs.submit(() -> new HttpsProbe(deps, proxy, url, capportApiUrl)
+ .sendProbe()));
}
final ArrayList<CaptivePortalProbeResult> completedProbes = new ArrayList<>();
@@ -2759,15 +2788,15 @@
}
private CaptivePortalProbeResult sendHttpAndHttpsParallelWithFallbackProbes(
- ProxyInfo proxy, URL httpsUrl, URL httpUrl) {
+ EvaluationThreadDeps deps, ProxyInfo proxy, URL httpsUrl, URL httpUrl) {
// Number of probes to wait for. If a probe completes with a conclusive answer
// it shortcuts the latch immediately by forcing the count to 0.
final CountDownLatch latch = new CountDownLatch(2);
final Uri capportApiUrl = getCaptivePortalApiUrl(mLinkProperties);
- final ProbeThread httpsProbe = new ProbeThread(latch, proxy, httpsUrl,
+ final ProbeThread httpsProbe = new ProbeThread(latch, deps, proxy, httpsUrl,
ValidationProbeEvent.PROBE_HTTPS, capportApiUrl);
- final ProbeThread httpProbe = new ProbeThread(latch, proxy, httpUrl,
+ final ProbeThread httpProbe = new ProbeThread(latch, deps, proxy, httpUrl,
ValidationProbeEvent.PROBE_HTTP, capportApiUrl);
try {
diff --git a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
index 834aa2d..0b05a5b 100644
--- a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
+++ b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
@@ -78,11 +78,17 @@
// is used to represent "infinite lease".
public static final String COLTYPE_ASSIGNEDV4ADDRESSEXPIRY = "BIGINT";
- // Please note that the group hint is only a *hint*, hence its name. The client can offer
- // this information to nudge the grouping in the decision it thinks is right, but it can't
- // decide for the memory store what is the same L3 network.
- public static final String COLNAME_GROUPHINT = "groupHint";
- public static final String COLTYPE_GROUPHINT = "TEXT";
+ // An optional cluster representing a notion of group owned by the client. The memory
+ // store uses this as a hint for grouping, but not as an overriding factor. The client
+ // can then use this to find networks belonging to a cluster. An example of this could
+ // be the SSID for WiFi, where same SSID-networks may not be the same L3 networks but
+ // it's still useful for managing networks.
+ // Note that "groupHint" is the legacy name of the column. The column should be renamed
+ // in the database – ALTER TABLE ${NetworkAttributesContract.TABLENAME RENAME} COLUMN
+ // groupHint TO cluster – but this has been postponed to reduce risk as the Mainline
+ // release winter imposes a lot of changes be pushed at the same time in the next release.
+ public static final String COLNAME_CLUSTER = "groupHint";
+ public static final String COLTYPE_CLUSTER = "TEXT";
public static final String COLNAME_DNSADDRESSES = "dnsAddresses";
// Stored in marshalled form as is
@@ -97,7 +103,7 @@
+ COLNAME_EXPIRYDATE + " " + COLTYPE_EXPIRYDATE + ", "
+ COLNAME_ASSIGNEDV4ADDRESS + " " + COLTYPE_ASSIGNEDV4ADDRESS + ", "
+ COLNAME_ASSIGNEDV4ADDRESSEXPIRY + " " + COLTYPE_ASSIGNEDV4ADDRESSEXPIRY + ", "
- + COLNAME_GROUPHINT + " " + COLTYPE_GROUPHINT + ", "
+ + COLNAME_CLUSTER + " " + COLTYPE_CLUSTER + ", "
+ COLNAME_DNSADDRESSES + " " + COLTYPE_DNSADDRESSES + ", "
+ COLNAME_MTU + " " + COLTYPE_MTU + ")";
public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
@@ -165,7 +171,7 @@
try {
if (oldVersion < 2) {
// upgrade from version 1 to version 2
- // since we starts from version 2, do nothing here
+ // since we start from version 2, do nothing here
}
if (oldVersion < 3) {
@@ -250,8 +256,8 @@
values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY,
attributes.assignedV4AddressExpiry);
}
- if (null != attributes.groupHint) {
- values.put(NetworkAttributesContract.COLNAME_GROUPHINT, attributes.groupHint);
+ if (null != attributes.cluster) {
+ values.put(NetworkAttributesContract.COLNAME_CLUSTER, attributes.cluster);
}
if (null != attributes.dnsAddresses) {
values.put(NetworkAttributesContract.COLNAME_DNSADDRESSES,
@@ -299,7 +305,7 @@
NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS, 0);
final long assignedV4AddressExpiry = getLong(cursor,
NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY, 0);
- final String groupHint = getString(cursor, NetworkAttributesContract.COLNAME_GROUPHINT);
+ final String cluster = getString(cursor, NetworkAttributesContract.COLNAME_CLUSTER);
final byte[] dnsAddressesBlob =
getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES);
final int mtu = getInt(cursor, NetworkAttributesContract.COLNAME_MTU, -1);
@@ -309,7 +315,7 @@
if (0 != assignedV4AddressExpiry) {
builder.setAssignedV4AddressExpiry(assignedV4AddressExpiry);
}
- builder.setGroupHint(groupHint);
+ builder.setCluster(cluster);
if (null != dnsAddressesBlob) {
builder.setDnsAddresses(decodeAddressList(dnsAddressesBlob));
}
@@ -596,6 +602,64 @@
return bestKey;
}
+ /**
+ * Delete a single entry by key.
+ *
+ * If |needWipe| is true, the data will be wiped from disk immediately. Otherwise, it will
+ * only be marked deleted, and overwritten by subsequent writes or reclaimed during the next
+ * maintenance window.
+ * Note that wiping data is a very expensive operation. This is meant for clients that need
+ * this data gone from disk immediately for security reasons. Functionally it makes no
+ * difference at all.
+ */
+ static StatusAndCount delete(@NonNull final SQLiteDatabase db, @NonNull final String l2key,
+ final boolean needWipe) {
+ return deleteEntriesWithColumn(db,
+ NetworkAttributesContract.COLNAME_L2KEY, l2key, needWipe);
+ }
+
+ /**
+ * Delete all entries that have a particular cluster value.
+ *
+ * If |needWipe| is true, the data will be wiped from disk immediately. Otherwise, it will
+ * only be marked deleted, and overwritten by subsequent writes or reclaimed during the next
+ * maintenance window.
+ * Note that wiping data is a very expensive operation. This is meant for clients that need
+ * this data gone from disk immediately for security reasons. Functionally it makes no
+ * difference at all.
+ */
+ static StatusAndCount deleteCluster(@NonNull final SQLiteDatabase db,
+ @NonNull final String cluster, final boolean needWipe) {
+ return deleteEntriesWithColumn(db,
+ NetworkAttributesContract.COLNAME_CLUSTER, cluster, needWipe);
+ }
+
+ // Delete all entries where the given column has the given value.
+ private static StatusAndCount deleteEntriesWithColumn(@NonNull final SQLiteDatabase db,
+ @NonNull final String column, @NonNull final String value, final boolean needWipe) {
+ db.beginTransaction();
+ int deleted = 0;
+ try {
+ deleted = db.delete(NetworkAttributesContract.TABLENAME,
+ column + "= ?", new String[] { value });
+ db.setTransactionSuccessful();
+ } catch (SQLiteException e) {
+ Log.e(TAG, "Could not delete from the memory store", e);
+ // Unclear what might have happened ; deleting records is not supposed to be able
+ // to fail barring a syntax error in the SQL query.
+ return new StatusAndCount(Status.ERROR_UNKNOWN, 0);
+ } finally {
+ db.endTransaction();
+ }
+
+ if (needWipe) {
+ final int vacuumStatus = vacuum(db);
+ // This is a problem for the client : return the failure
+ if (Status.SUCCESS != vacuumStatus) return new StatusAndCount(vacuumStatus, deleted);
+ }
+ return new StatusAndCount(Status.SUCCESS, deleted);
+ }
+
// Drops all records that are expired. Relevance has decayed to zero of these records. Returns
// an int out of Status.{SUCCESS, ERROR_*}
static int dropAllExpiredRecords(@NonNull final SQLiteDatabase db) {
@@ -702,4 +766,13 @@
final int columnIndex = cursor.getColumnIndex(columnName);
return (columnIndex >= 0) ? cursor.getLong(columnIndex) : defaultValue;
}
+ private static int vacuum(@NonNull final SQLiteDatabase db) {
+ try {
+ db.execSQL("VACUUM");
+ return Status.SUCCESS;
+ } catch (SQLiteException e) {
+ // Vacuuming may fail from lack of storage, because it makes a copy of the database.
+ return Status.ERROR_STORAGE;
+ }
+ }
}
diff --git a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
index cd29e0d..ae9c875 100644
--- a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
+++ b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
@@ -33,6 +33,7 @@
import android.net.ipmemorystore.IOnL2KeyResponseListener;
import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
+import android.net.ipmemorystore.IOnStatusAndCountListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -116,7 +117,11 @@
// TODO : investigate replacing this scheme with a scheme where each thread has its own
// instance of the database, as it may be faster. It is likely however that IpMemoryStore
// operations are mostly IO-bound anyway, and additional contention is unlikely to bring
- // benefits. Alternatively, a read-write lock might increase throughput.
+ // benefits. Alternatively, a read-write lock might increase throughput. Also if doing
+ // this work, care must be taken around the privacy-preserving VACUUM operations as
+ // VACUUM will fail if there are other open transactions at the same time, and using
+ // multiple threads will open the possibility of this failure happening, threatening
+ // the privacy guarantees.
mExecutor = Executors.newSingleThreadExecutor();
RegularMaintenanceJobService.schedule(mContext, this);
}
@@ -405,6 +410,56 @@
}
/**
+ * Delete a single entry.
+ *
+ * @param l2Key The L2 key of the entry to delete.
+ * @param needWipe Whether the data must be wiped from disk immediately for security reasons.
+ * This is very expensive and makes no functional difference ; only pass
+ * true if security requires this data must be removed from disk immediately.
+ * @param listener A listener that will be invoked to inform of the completion of this call,
+ * or null if the client is not interested in learning about success/failure.
+ * returns (through the listener) A status to indicate success and the number of deleted records
+ */
+ public void delete(@NonNull final String l2Key, final boolean needWipe,
+ @Nullable final IOnStatusAndCountListener listener) {
+ mExecutor.execute(() -> {
+ try {
+ final StatusAndCount res = IpMemoryStoreDatabase.delete(mDb, l2Key, needWipe);
+ if (null != listener) listener.onComplete(makeStatus(res.status), res.count);
+ } catch (final RemoteException e) {
+ // Client at the other end died
+ }
+ });
+ }
+
+ /**
+ * Delete all entries in a cluster.
+ *
+ * This method will delete all entries in the memory store that have the cluster attribute
+ * passed as an argument.
+ *
+ * @param cluster The cluster to delete.
+ * @param needWipe Whether the data must be wiped from disk immediately for security reasons.
+ * This is very expensive and makes no functional difference ; only pass
+ * true if security requires this data must be removed from disk immediately.
+ * @param listener A listener that will be invoked to inform of the completion of this call,
+ * or null if the client is not interested in learning about success/failure.
+ * returns (through the listener) A status to indicate success and the number of deleted records
+ */
+ public void deleteCluster(@NonNull final String cluster, final boolean needWipe,
+ @Nullable final IOnStatusAndCountListener listener) {
+ mExecutor.execute(() -> {
+ try {
+ final StatusAndCount res =
+ IpMemoryStoreDatabase.deleteCluster(mDb, cluster, needWipe);
+ if (null != listener) listener.onComplete(makeStatus(res.status), res.count);
+ } catch (final RemoteException e) {
+ // Client at the other end died
+ }
+ });
+ }
+
+ /**
* Wipe the data in IpMemoryStore database upon network factory reset.
*/
@Override
diff --git a/src/com/android/server/connectivity/ipmemorystore/StatusAndCount.java b/src/com/android/server/connectivity/ipmemorystore/StatusAndCount.java
new file mode 100644
index 0000000..2cbe843
--- /dev/null
+++ b/src/com/android/server/connectivity/ipmemorystore/StatusAndCount.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity.ipmemorystore;
+
+/**
+ * Small data class to wrap a Status and an int.
+ */
+public class StatusAndCount {
+ public final int status;
+ public final int count;
+ public StatusAndCount(final int status, final int count) {
+ this.status = status;
+ this.count = count;
+ }
+}
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
index 6a98696..3e38a00 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
@@ -186,7 +186,7 @@
private static final int PACKET_TIMEOUT_MS = 5_000;
private static final int TEST_TIMEOUT_MS = 400;
private static final String TEST_L2KEY = "some l2key";
- private static final String TEST_GROUPHINT = "some grouphint";
+ private static final String TEST_CLUSTER = "some cluster";
private static final int TEST_LEASE_DURATION_S = 3_600; // 1 hour
// TODO: move to NetlinkConstants, NetworkStackConstants, or OsConstants.
@@ -267,7 +267,7 @@
private static final String TEST_DHCP_ROAM_SSID = "0001docomo";
private static final String TEST_DHCP_ROAM_BSSID = "00:4e:35:17:98:55";
private static final String TEST_DHCP_ROAM_L2KEY = "roaming_l2key";
- private static final String TEST_DHCP_ROAM_GROUPHINT = "roaming_group_hint";
+ private static final String TEST_DHCP_ROAM_CLUSTER = "roaming_cluster";
private static final byte[] TEST_AP_OUI = new byte[] { 0x00, 0x1A, 0x11 };
private class Dependencies extends IpClient.Dependencies {
@@ -600,7 +600,7 @@
throws RemoteException {
ProvisioningConfiguration.Builder prov = new ProvisioningConfiguration.Builder()
.withoutIpReachabilityMonitor()
- .withLayer2Information(new Layer2Information(TEST_L2KEY, TEST_GROUPHINT,
+ .withLayer2Information(new Layer2Information(TEST_L2KEY, TEST_CLUSTER,
MacAddress.fromString(TEST_DEFAULT_BSSID)))
.withoutIPv6();
if (isPreconnectionEnabled) prov.withPreconnection();
@@ -1092,7 +1092,7 @@
.setAssignedV4Address(CLIENT_ADDR)
.setAssignedV4AddressExpiry(Long.MAX_VALUE) // lease is always valid
.setMtu(new Integer(TEST_DEFAULT_MTU))
- .setGroupHint(TEST_GROUPHINT)
+ .setCluster(TEST_CLUSTER)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), false /* timeout */);
assertTrue(packet instanceof DhcpRequestPacket);
@@ -1105,7 +1105,7 @@
.setAssignedV4Address(CLIENT_ADDR)
.setAssignedV4AddressExpiry(EXPIRED_LEASE)
.setMtu(new Integer(TEST_DEFAULT_MTU))
- .setGroupHint(TEST_GROUPHINT)
+ .setCluster(TEST_CLUSTER)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), false /* timeout */);
assertTrue(packet instanceof DhcpDiscoverPacket);
@@ -1124,7 +1124,7 @@
.setAssignedV4Address(CLIENT_ADDR)
.setAssignedV4AddressExpiry(System.currentTimeMillis() + 3_600_000)
.setMtu(new Integer(TEST_DEFAULT_MTU))
- .setGroupHint(TEST_GROUPHINT)
+ .setCluster(TEST_CLUSTER)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), true /* timeout */);
assertTrue(packet instanceof DhcpDiscoverPacket);
@@ -1135,7 +1135,7 @@
final DhcpPacket packet = getReplyFromDhcpLease(
new NetworkAttributes.Builder()
.setMtu(new Integer(TEST_DEFAULT_MTU))
- .setGroupHint(TEST_GROUPHINT)
+ .setCluster(TEST_CLUSTER)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), false /* timeout */);
assertTrue(packet instanceof DhcpDiscoverPacket);
@@ -1772,14 +1772,14 @@
@Test
public void testDhcpClientPreconnection_WithoutLayer2InfoWhenStartingProv() throws Exception {
- // For FILS connection, current bssid (also l2key and grouphint) is still null when
+ // For FILS connection, current bssid (also l2key and cluster) is still null when
// starting provisioning since the L2 link hasn't been established yet. Ensure that
// IpClient won't crash even if initializing an Layer2Info class with null members.
ProvisioningConfiguration.Builder prov = new ProvisioningConfiguration.Builder()
.withoutIpReachabilityMonitor()
.withoutIPv6()
.withPreconnection()
- .withLayer2Information(new Layer2Information(null /* l2key */, null /* grouphint */,
+ .withLayer2Information(new Layer2Information(null /* l2key */, null /* cluster */,
null /* bssid */));
mIpc.startProvisioning(prov.build());
@@ -2076,7 +2076,7 @@
final Layer2InformationParcelable roamingInfo = new Layer2InformationParcelable();
roamingInfo.bssid = MacAddress.fromString(TEST_DHCP_ROAM_BSSID);
roamingInfo.l2Key = TEST_DHCP_ROAM_L2KEY;
- roamingInfo.groupHint = TEST_DHCP_ROAM_GROUPHINT;
+ roamingInfo.cluster = TEST_DHCP_ROAM_CLUSTER;
mIpc.updateLayer2Information(roamingInfo);
currentTime = System.currentTimeMillis();
diff --git a/tests/lib/multivariant/com/android/testutils/PacketFilter.kt b/tests/lib/multivariant/com/android/testutils/PacketFilter.kt
new file mode 100644
index 0000000..cd8d6a5
--- /dev/null
+++ b/tests/lib/multivariant/com/android/testutils/PacketFilter.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 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.testutils
+
+import java.util.function.Predicate
+
+const val ETHER_TYPE_OFFSET = 12
+const val ETHER_HEADER_LENGTH = 14
+const val IPV4_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 9
+const val IPV4_CHECKSUM_OFFSET = ETHER_HEADER_LENGTH + 10
+const val IPV4_HEADER_LENGTH = 20
+const val IPV4_UDP_OFFSET = ETHER_HEADER_LENGTH + IPV4_HEADER_LENGTH
+const val BOOTP_OFFSET = IPV4_UDP_OFFSET + 8
+const val BOOTP_TID_OFFSET = BOOTP_OFFSET + 4
+const val BOOTP_CLIENT_MAC_OFFSET = BOOTP_OFFSET + 28
+const val DHCP_OPTIONS_OFFSET = BOOTP_OFFSET + 240
+
+/**
+ * A [Predicate] that matches a [ByteArray] if it contains the specified [bytes] at the specified
+ * [offset].
+ */
+class OffsetFilter(val offset: Int, vararg val bytes: Byte) : Predicate<ByteArray> {
+ override fun test(packet: ByteArray) =
+ bytes.withIndex().all { it.value == packet[offset + it.index] }
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv4 datagram.
+ */
+class IPv4UdpFilter : Predicate<ByteArray> {
+ private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x00 /* IPv4 */).and(
+ OffsetFilter(IPV4_PROTOCOL_OFFSET, 17 /* UDP */))
+ override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches ethernet-encapped DHCP packets sent from a DHCP client.
+ */
+class DhcpClientPacketFilter : Predicate<ByteArray> {
+ private val impl = IPv4UdpFilter()
+ .and(OffsetFilter(IPV4_UDP_OFFSET /* source port */, 0x00, 0x44 /* 68 */))
+ .and(OffsetFilter(IPV4_UDP_OFFSET + 2 /* dest port */, 0x00, 0x43 /* 67 */))
+ override fun test(t: ByteArray) = impl.test(t)
+}
+
+/**
+ * A [Predicate] that matches a [ByteArray] if it contains a ethernet-encapped DHCP packet that
+ * contains the specified option with the specified [bytes] as value.
+ */
+class DhcpOptionFilter(val option: Byte, vararg val bytes: Byte) : Predicate<ByteArray> {
+ override fun test(packet: ByteArray): Boolean {
+ val option = findDhcpOption(packet, option) ?: return false
+ return option.contentEquals(bytes)
+ }
+}
+
+/**
+ * Find a DHCP option in a packet and return its value, if found.
+ */
+fun findDhcpOption(packet: ByteArray, option: Byte): ByteArray? =
+ findOptionOffset(packet, option, DHCP_OPTIONS_OFFSET)?.let {
+ val optionLen = packet[it + 1]
+ return packet.copyOfRange(it + 2 /* type, length bytes */, it + 2 + optionLen)
+ }
+
+private tailrec fun findOptionOffset(packet: ByteArray, option: Byte, searchOffset: Int): Int? {
+ if (packet.size <= searchOffset + 2 /* type, length bytes */) return null
+
+ return if (packet[searchOffset] == option) searchOffset else {
+ val optionLen = packet[searchOffset + 1]
+ findOptionOffset(packet, option, searchOffset + 2 + optionLen)
+ }
+}
diff --git a/tests/lib/src/com/android/testutils/TapPacketReader.java b/tests/lib/src/com/android/testutils/TapPacketReader.java
index c68e5a5..e55ed44 100644
--- a/tests/lib/src/com/android/testutils/TapPacketReader.java
+++ b/tests/lib/src/com/android/testutils/TapPacketReader.java
@@ -19,6 +19,7 @@
import android.net.util.PacketReader;
import android.os.Handler;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.FileDescriptor;
@@ -26,12 +27,16 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+
+import kotlin.Lazy;
+import kotlin.LazyKt;
public class TapPacketReader extends PacketReader {
private final FileDescriptor mTapFd;
- private final LinkedBlockingQueue<byte[]> mReceivedPackets = new LinkedBlockingQueue<byte[]>();
+ private final ArrayTrackRecord<byte[]> mReceivedPackets = new ArrayTrackRecord<>();
+ private final Lazy<ArrayTrackRecord<byte[]>.ReadHead> mReadHead =
+ LazyKt.lazy(mReceivedPackets::newReadHead);
public TapPacketReader(Handler h, FileDescriptor tapFd, int maxPacketSize) {
super(h, maxPacketSize);
@@ -46,23 +51,25 @@
@Override
protected void handlePacket(byte[] recvbuf, int length) {
final byte[] newPacket = Arrays.copyOf(recvbuf, length);
- if (!mReceivedPackets.offer(newPacket)) {
+ if (!mReceivedPackets.add(newPacket)) {
throw new AssertionError("More than " + Integer.MAX_VALUE + " packets outstanding!");
}
}
/**
* Get the next packet that was received on the interface.
- *
*/
@Nullable
public byte[] popPacket(long timeoutMs) {
- try {
- return mReceivedPackets.poll(timeoutMs, TimeUnit.MILLISECONDS);
- } catch (InterruptedException e) {
- // Fall through
- }
- return null;
+ return mReadHead.getValue().poll(timeoutMs, packet -> true);
+ }
+
+ /**
+ * Get the next packet that was received on the interface and matches the specified filter.
+ */
+ @Nullable
+ public byte[] popPacket(long timeoutMs, @NonNull Predicate<byte[]> filter) {
+ return mReadHead.getValue().poll(timeoutMs, filter::test);
}
public void sendResponse(final ByteBuffer packet) throws IOException {
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index fe6dddb..e2b8e4f 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -93,7 +93,7 @@
private static final MacAddress TEST_MAC = MacAddress.fromString("00:00:5E:00:53:01");
private static final int TEST_TIMEOUT_MS = 400;
private static final String TEST_L2KEY = "some l2key";
- private static final String TEST_GROUPHINT = "some grouphint";
+ private static final String TEST_CLUSTER = "some cluster";
private static final String TEST_GLOBAL_ADDRESS = "1234:4321::548d:2db2:4fcf:ef75/64";
private static final String[] TEST_LOCAL_ADDRESSES = {
@@ -357,7 +357,7 @@
final String iface = TEST_IFNAME;
final IpClient ipc = makeIpClient(iface);
final String l2Key = TEST_L2KEY;
- final String groupHint = TEST_GROUPHINT;
+ final String cluster = TEST_CLUSTER;
ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
.withoutIPv4()
@@ -370,7 +370,7 @@
verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setNeighborDiscoveryOffload(true);
verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
verify(mCb, never()).onProvisioningFailure(any());
- ipc.setL2KeyAndGroupHint(l2Key, groupHint);
+ ipc.setL2KeyAndCluster(l2Key, cluster);
for (String addr : TEST_LOCAL_ADDRESSES) {
String[] parts = addr.split("/");
@@ -394,7 +394,7 @@
want.setInterfaceName(iface);
verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(want);
verifyNetworkAttributesStored(l2Key, new NetworkAttributes.Builder()
- .setGroupHint(groupHint)
+ .setCluster(cluster)
.build());
}
diff --git a/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java b/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java
index 8fc44a4..49cea7d 100644
--- a/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java
+++ b/tests/unit/src/android/net/shared/ProvisioningConfigurationTest.java
@@ -84,7 +84,7 @@
mConfig.mDisplayName = "test_config";
mConfig.mEnablePreconnection = false;
mConfig.mScanResultInfo = makeScanResultInfo("ssid");
- mConfig.mLayer2Info = new Layer2Information("some l2key", "some groupHint",
+ mConfig.mLayer2Info = new Layer2Information("some l2key", "some cluster",
MacAddress.fromString("00:01:02:03:04:05"));
// Any added field must be included in equals() to be tested properly
assertFieldCountEquals(15, ProvisioningConfiguration.class);
@@ -164,11 +164,11 @@
assertNotEqualsAfterChange(c -> c.mScanResultInfo = null);
assertNotEqualsAfterChange(c -> c.mScanResultInfo = makeScanResultInfo("another ssid"));
assertNotEqualsAfterChange(c -> c.mLayer2Info = new Layer2Information("another l2key",
- "some groupHint", MacAddress.fromString("00:01:02:03:04:05")));
+ "some cluster", MacAddress.fromString("00:01:02:03:04:05")));
assertNotEqualsAfterChange(c -> c.mLayer2Info = new Layer2Information("some l2key",
- "another groupHint", MacAddress.fromString("00:01:02:03:04:05")));
+ "another cluster", MacAddress.fromString("00:01:02:03:04:05")));
assertNotEqualsAfterChange(c -> c.mLayer2Info = new Layer2Information("some l2key",
- "some groupHint", MacAddress.fromString("01:02:03:04:05:06")));
+ "some cluster", MacAddress.fromString("01:02:03:04:05:06")));
assertNotEqualsAfterChange(c -> c.mLayer2Info = null);
assertFieldCountEquals(15, ProvisioningConfiguration.class);
}
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index 67b8a9b..e72bcda 100644
--- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -52,6 +52,7 @@
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
import static com.android.networkstack.util.DnsUtils.PRIVATE_DNS_PROBE_HOST_SUFFIX;
+import static com.android.server.connectivity.NetworkMonitor.INITIAL_REEVALUATE_DELAY_MS;
import static com.android.server.connectivity.NetworkMonitor.extractCharset;
import static junit.framework.Assert.assertEquals;
@@ -1112,10 +1113,13 @@
verify(mFallbackConnection, times(1)).getResponseCode();
verify(mOtherFallbackConnection, never()).getResponseCode();
- // Second check uses the URL chosen by Random
- final CaptivePortalProbeResult result = monitor.isCaptivePortal();
- assertTrue(result.isPortal());
- verify(mOtherFallbackConnection, times(1)).getResponseCode();
+ // Second check should be triggered automatically after the reevaluate delay, and uses the
+ // URL chosen by mRandom
+ // This test is appropriate to cover reevaluate behavior as long as the timeout is short
+ assertTrue(INITIAL_REEVALUATE_DELAY_MS < 2000);
+ verify(mOtherFallbackConnection, timeout(INITIAL_REEVALUATE_DELAY_MS + HANDLER_TIMEOUT_MS))
+ .getResponseCode();
+ verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);
}
@Test
@@ -1253,7 +1257,7 @@
@Test
public void testIsCaptivePortal_CapportApiInvalidContent() throws Exception {
assumeTrue(CaptivePortalDataShimImpl.isSupported());
- setStatus(mHttpsConnection, 204);
+ setSslException(mHttpsConnection);
setPortal302(mHttpConnection);
setApiContent(mCapportApiConnection, "{SomeInvalidText");
runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES,
@@ -1264,6 +1268,36 @@
verify(mHttpConnection).getResponseCode();
}
+ private void runCapportApiInvalidUrlTest(String url) throws Exception {
+ assumeTrue(CaptivePortalDataShimImpl.isSupported());
+ setSslException(mHttpsConnection);
+ setPortal302(mHttpConnection);
+ final LinkProperties lp = new LinkProperties(TEST_LINK_PROPERTIES);
+ lp.setCaptivePortalApiUrl(Uri.parse(url));
+ runNetworkTest(makeCapportLPs(), CELL_METERED_CAPABILITIES,
+ VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */,
+ TEST_LOGIN_URL);
+
+ verify(mCallbacks, never()).notifyCaptivePortalDataChanged(any());
+ verify(mCapportApiConnection, never()).getInputStream();
+ verify(mHttpConnection).getResponseCode();
+ }
+
+ @Test
+ public void testIsCaptivePortal_HttpIsInvalidCapportApiScheme() throws Exception {
+ runCapportApiInvalidUrlTest("http://capport.example.com");
+ }
+
+ @Test
+ public void testIsCaptivePortal_FileIsInvalidCapportApiScheme() throws Exception {
+ runCapportApiInvalidUrlTest("file://localhost/myfile");
+ }
+
+ @Test
+ public void testIsCaptivePortal_InvalidUrlFormat() throws Exception {
+ runCapportApiInvalidUrlTest("ThisIsNotAValidUrl");
+ }
+
@Test @IgnoreUpTo(Build.VERSION_CODES.Q)
public void testIsCaptivePortal_CapportApiNotSupported() throws Exception {
// Test that on a R+ device, if NetworkStack was compiled without CaptivePortalData support
diff --git a/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
index ac05783..c0bdc4c 100644
--- a/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
+++ b/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
@@ -20,6 +20,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.junit.Assert.fail;
@@ -33,6 +34,7 @@
import android.net.ipmemorystore.IOnL2KeyResponseListener;
import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
+import android.net.ipmemorystore.IOnStatusAndCountListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributes;
import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -44,6 +46,7 @@
import android.os.IBinder;
import android.os.RemoteException;
+import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -69,10 +72,13 @@
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
/** Unit tests for {@link IpMemoryStoreService}. */
@@ -152,7 +158,7 @@
/** Helper method to build test network attributes */
private static NetworkAttributes.Builder buildTestNetworkAttributes(
- final Inet4Address ipAddress, final long expiry, final String hint,
+ final Inet4Address ipAddress, final long expiry, final String cluster,
final List<InetAddress> dnsServers, final int mtu) {
final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
if (null != ipAddress) {
@@ -161,8 +167,8 @@
if (LEASE_EXPIRY_NULL != expiry) {
na.setAssignedV4AddressExpiry(expiry);
}
- if (null != hint) {
- na.setGroupHint(hint);
+ if (null != cluster) {
+ na.setCluster(cluster);
}
if (null != dnsServers) {
na.setDnsAddresses(dnsServers);
@@ -198,6 +204,32 @@
};
}
+ /** Helper method to make a vanilla IOnStatusAndCountListener */
+ private IOnStatusAndCountListener onDeleteStatus(BiConsumer<Status, Integer> functor) {
+ return new IOnStatusAndCountListener() {
+ @Override
+ public void onComplete(final StatusParcelable statusParcelable, final int deletedCount)
+ throws RemoteException {
+ functor.accept(new Status(statusParcelable), deletedCount);
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return null;
+ }
+
+ @Override
+ public int getInterfaceVersion() {
+ return this.VERSION;
+ }
+
+ @Override
+ public String getInterfaceHash() {
+ return this.HASH;
+ }
+ };
+ }
+
/** Helper method to make an IOnBlobRetrievedListener */
private interface OnBlobRetrievedListener {
void onBlobRetrieved(Status status, String l2Key, String name, byte[] data);
@@ -339,17 +371,18 @@
}
}
- // Helper method to store network attributes to database
- private void storeAttributes(final String l2Key, final NetworkAttributes na) {
- storeAttributes("Did not complete storing attributes", l2Key, na);
+ // Helper method to store network attributes to database. Returns the stored attributes.
+ private NetworkAttributes storeAttributes(final String l2Key, final NetworkAttributes na) {
+ return storeAttributes("Did not complete storing attributes", l2Key, na);
}
- private void storeAttributes(final String timeoutMessage, final String l2Key,
+ private NetworkAttributes storeAttributes(final String timeoutMessage, final String l2Key,
final NetworkAttributes na) {
doLatched(timeoutMessage, latch -> mService.storeNetworkAttributes(l2Key, na.toParcelable(),
onStatus(status -> {
assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
latch.countDown();
})));
+ return na;
}
// Helper method to store blob data to database
@@ -384,7 +417,7 @@
try {
final NetworkAttributes.Builder na = buildTestNetworkAttributes(
(Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
- "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
+ "cluster1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
219);
final long time = System.currentTimeMillis() - 1;
for (int i = 0; i < fakeDataCount; i++) {
@@ -423,7 +456,7 @@
final String l2Key = FAKE_KEYS[0];
final NetworkAttributes.Builder na = buildTestNetworkAttributes(
(Inet4Address) Inet4Address.getByName("1.2.3.4"),
- System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
+ System.currentTimeMillis() + 7_200_000, "cluster1", null, 219);
NetworkAttributes attributes = na.build();
storeAttributes(l2Key, attributes);
@@ -452,7 +485,7 @@
assertEquals(attributes.assignedV4Address, attr.assignedV4Address);
assertEquals(attributes.assignedV4AddressExpiry,
attr.assignedV4AddressExpiry);
- assertEquals(attributes.groupHint, attr.groupHint);
+ assertEquals(attributes.cluster, attr.cluster);
assertEquals(attributes.mtu, attr.mtu);
assertEquals(attributes2.dnsAddresses, attr.dnsAddresses);
latch.countDown();
@@ -546,28 +579,37 @@
})));
}
- @Test
- public void testFindL2Key() throws UnknownHostException {
+ private List<NetworkAttributes> storeFixture() throws Exception {
+ final ArrayList<NetworkAttributes> stored = new ArrayList<>();
final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
- na.setGroupHint("hint0");
- storeAttributes(FAKE_KEYS[0], na.build());
+ na.setCluster("cluster0");
+ stored.add(storeAttributes(FAKE_KEYS[0], na.build()));
na.setDnsAddresses(Arrays.asList(
new InetAddress[] {Inet6Address.getByName("8D56:9AF1::08EE:20F1")}));
- na.setMtu(219);
- storeAttributes(FAKE_KEYS[1], na.build());
+ na.setMtu(208);
+ stored.add(storeAttributes(FAKE_KEYS[1], na.build()));
na.setMtu(null);
na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
na.setDnsAddresses(Arrays.asList(
new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
- na.setGroupHint("hint1");
- storeAttributes(FAKE_KEYS[2], na.build());
+ na.setCluster("cluster1");
+ stored.add(storeAttributes(FAKE_KEYS[2], na.build()));
na.setMtu(219);
- storeAttributes(FAKE_KEYS[3], na.build());
+ stored.add(storeAttributes(FAKE_KEYS[3], na.build()));
+ na.setCluster(null);
na.setMtu(240);
- storeAttributes(FAKE_KEYS[4], na.build());
+ stored.add(storeAttributes(FAKE_KEYS[4], na.build()));
na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("5.6.7.8"));
- storeAttributes(FAKE_KEYS[5], na.build());
+ stored.add(storeAttributes(FAKE_KEYS[5], na.build()));
+ return stored;
+ }
+
+ @Test
+ public void testFindL2Key() throws Exception {
+ final List<NetworkAttributes> stored = storeFixture();
+ final NetworkAttributes.Builder na = new NetworkAttributes.Builder(
+ stored.get(stored.size() - 1));
// Matches key 5 exactly
doLatched("Did not finish finding L2Key", latch ->
@@ -589,6 +631,7 @@
})));
// Closest to key 3 (indeed, identical)
+ na.setCluster("cluster1");
na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
na.setMtu(219);
doLatched("Did not finish finding L2Key", latch ->
@@ -599,8 +642,8 @@
latch.countDown();
})));
- // Group hint alone must not be strong enough to override the rest
- na.setGroupHint("hint0");
+ // Cluster alone must not be strong enough to override the rest
+ na.setCluster("cluster0");
doLatched("Did not finish finding L2Key", latch ->
mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
assertTrue("Retrieve network sameness not successful : " + status.resultCode,
@@ -610,7 +653,7 @@
})));
// Still closest to key 3, though confidence is lower
- na.setGroupHint("hint1");
+ na.setCluster("cluster1");
na.setDnsAddresses(null);
doLatched("Did not finish finding L2Key", latch ->
mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
@@ -620,18 +663,18 @@
latch.countDown();
})));
- // But changing the MTU makes this closer to key 4
- na.setMtu(240);
+ // But changing the MTU makes this closer to key 2
+ na.setMtu(208);
doLatched("Did not finish finding L2Key", latch ->
mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
assertTrue("Retrieve network sameness not successful : " + status.resultCode,
status.isSuccess());
- assertEquals(FAKE_KEYS[4], key);
+ assertEquals(FAKE_KEYS[2], key);
latch.countDown();
})));
// MTU alone not strong enough to make this group-close
- na.setGroupHint(null);
+ na.setCluster(null);
na.setDnsAddresses(null);
na.setAssignedV4Address(null);
doLatched("Did not finish finding L2Key", latch ->
@@ -657,7 +700,7 @@
public void testIsSameNetwork() throws UnknownHostException {
final NetworkAttributes.Builder na = buildTestNetworkAttributes(
(Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
- "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
+ "cluster1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
219);
storeAttributes(FAKE_KEYS[0], na.build());
@@ -668,10 +711,10 @@
na.setMtu(200);
storeAttributes(FAKE_KEYS[2], na.build());
- // Hopefully different MTU, assigned V4 address and grouphint make a different network,
+ // Hopefully different MTU, assigned V4 address and cluster make a different network,
// even with identical DNS addresses
na.setAssignedV4Address(null);
- na.setGroupHint("hint2");
+ na.setCluster("cluster2");
storeAttributes(FAKE_KEYS[3], na.build());
assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[1], SameL3NetworkResponse.NETWORK_SAME);
@@ -691,6 +734,63 @@
})));
}
+ private NetworkAttributes fetchAttributes(@NonNull final String l2Key) throws Exception {
+ final CompletableFuture<NetworkAttributes> f = new CompletableFuture<>();
+ mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
+ (status, key, attr) -> {
+ assertTrue("Retrieve network attributes not successful : "
+ + status.resultCode, status.isSuccess());
+ f.complete(attr);
+ }));
+ return f.get(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ }
+
+ private void delete(@NonNull final String l2Key) {
+ doLatched("Did not finish deleting", latch ->
+ mService.delete(l2Key, false /* needWipe */, onDeleteStatus((status, deleted) -> {
+ assertTrue("Deleting failed :" + status.resultCode, status.isSuccess());
+ assertEquals("Deleting count != 1 :" + deleted, 1, deleted.intValue());
+ latch.countDown();
+ })), LONG_TIMEOUT_MS);
+ }
+
+ @Test
+ public void testDelete() throws Exception {
+ storeFixture();
+
+ delete(FAKE_KEYS[0]);
+ delete(FAKE_KEYS[3]);
+
+ assertNull(fetchAttributes(FAKE_KEYS[0]));
+ assertNotNull(fetchAttributes(FAKE_KEYS[1]));
+ assertNotNull(fetchAttributes(FAKE_KEYS[2]));
+ assertNull(fetchAttributes(FAKE_KEYS[3]));
+ assertNotNull(fetchAttributes(FAKE_KEYS[4]));
+ assertNotNull(fetchAttributes(FAKE_KEYS[5]));
+ }
+
+ @Test
+ public void testDeleteCluster() throws Exception {
+ storeFixture();
+
+ doLatched("Did not finish deleting", latch ->
+ mService.deleteCluster("cluster1", false /* needWipe */,
+ onDeleteStatus((status, deletedCount) -> {
+ assertTrue("Delete failed : " + status.resultCode, status.isSuccess());
+ // The fixture stores 2 keys under "cluster1"
+ assertEquals("Unexpected deleted count : " + deletedCount,
+ 2, deletedCount.intValue());
+ latch.countDown();
+ })), LONG_TIMEOUT_MS);
+
+ assertNotNull(fetchAttributes(FAKE_KEYS[0]));
+ assertNotNull(fetchAttributes(FAKE_KEYS[1]));
+ assertNull(fetchAttributes(FAKE_KEYS[2]));
+ assertNull(fetchAttributes(FAKE_KEYS[3]));
+ assertNotNull(fetchAttributes(FAKE_KEYS[4]));
+ assertNotNull(fetchAttributes(FAKE_KEYS[5]));
+ }
+
@Test
public void testFullMaintenance() throws Exception {
copyTestData(mDbFile);
@@ -761,7 +861,7 @@
// store network attributes
final NetworkAttributes.Builder na = buildTestNetworkAttributes(
(Inet4Address) Inet4Address.getByName("1.2.3.4"),
- System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
+ System.currentTimeMillis() + 7_200_000, "cluster1", null, 219);
storeAttributes(l2Key, na.build());
// store private data blob