diff options
author | Chalard Jean <jchalard@google.com> | 2020-05-29 12:40:54 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-05-29 12:40:54 +0000 |
commit | c71f9fcd2c50ac21ce23a717e274b9d8800ea668 (patch) | |
tree | 9c57dbbca9f8baee4ab89644bfc5df75397e250b | |
parent | 4ebd0d5cfc0cc25605f3e2c87d02512bb84820f6 (diff) | |
parent | 1e2e741071140b5f911db91b2008bda8dbdb732e (diff) |
Merge "Implement delete methods" into rvc-dev am: 1e2e741071
Change-Id: Idc718c8adadf76acb5a6c8157118bc86b1ce559a
25 files changed, 771 insertions, 19 deletions
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp index 43d482f..3ddf633 100644 --- a/common/networkstackclient/Android.bp +++ b/common/networkstackclient/Android.bp @@ -44,6 +44,7 @@ aidl_interface { "4", "5", "6", + "7", ], visibility: [ "//system/tools/aidl/build", 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 @@ interface IIpMemoryStore { 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/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.IOnBlobRetrievedListener; 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 @@ oneway interface IIpMemoryStore { * @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 @@ oneway interface IIpMemoryStore { * 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.content.Context; 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 @@ public abstract class IpMemoryStoreClient { } /** + * 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/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 104ac79..2e444fe 100644 --- a/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java +++ b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java @@ -218,6 +218,22 @@ public class NetworkAttributes { 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. 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/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java index be338e5..0b05a5b 100644 --- a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java +++ b/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java @@ -602,6 +602,64 @@ public class IpMemoryStoreDatabase { 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) { @@ -708,4 +766,13 @@ public class IpMemoryStoreDatabase { 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.IOnBlobRetrievedListener; 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 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub { // 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 @@ public class IpMemoryStoreService extends IIpMemoryStore.Stub { } /** + * 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/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java index 533bbc3..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 com.android.server.connectivity.ipmemorystore.RegularMaintenanceJo 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.IOnBlobRetrievedListener; 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.ConditionVariable; 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.Inet4Address; 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}. */ @@ -198,6 +204,32 @@ public class IpMemoryStoreServiceTest { }; } + /** 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 @@ public class IpMemoryStoreServiceTest { } } - // 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 @@ -546,28 +579,37 @@ public class IpMemoryStoreServiceTest { }))); } - @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.setCluster("cluster0"); - storeAttributes(FAKE_KEYS[0], na.build()); + 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.setCluster("cluster1"); - storeAttributes(FAKE_KEYS[2], na.build()); + 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 @@ public class IpMemoryStoreServiceTest { }))); // 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 -> @@ -620,13 +663,13 @@ public class IpMemoryStoreServiceTest { 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(); }))); @@ -691,6 +734,63 @@ public class IpMemoryStoreServiceTest { }))); } + 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); |