diff options
Diffstat (limited to 'common/networkstackclient/src')
35 files changed, 1980 insertions, 0 deletions
diff --git a/common/networkstackclient/src/android/net/DhcpResultsParcelable.aidl b/common/networkstackclient/src/android/net/DhcpResultsParcelable.aidl new file mode 100644 index 0000000..c98d9c2 --- /dev/null +++ b/common/networkstackclient/src/android/net/DhcpResultsParcelable.aidl @@ -0,0 +1,28 @@ +/** + * 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 perNmissions and + * limitations under the License. + */ + +package android.net; + +import android.net.StaticIpConfiguration; + +parcelable DhcpResultsParcelable { + StaticIpConfiguration baseConfiguration; + int leaseDuration; + int mtu; + String serverAddress; + String vendorInfo; + String serverHostName; +} diff --git a/common/networkstackclient/src/android/net/IIpMemoryStore.aidl b/common/networkstackclient/src/android/net/IIpMemoryStore.aidl new file mode 100644 index 0000000..add221a --- /dev/null +++ b/common/networkstackclient/src/android/net/IIpMemoryStore.aidl @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2018 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; + +import android.net.ipmemorystore.Blob; +import android.net.ipmemorystore.NetworkAttributesParcelable; +import android.net.ipmemorystore.IOnBlobRetrievedListener; +import android.net.ipmemorystore.IOnL2KeyResponseListener; +import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener; +import android.net.ipmemorystore.IOnSameL3NetworkResponseListener; +import android.net.ipmemorystore.IOnStatusListener; + +/** {@hide} */ +oneway interface IIpMemoryStore { + /** + * Store network attributes for a given L2 key. + * If L2Key is null, choose automatically from the attributes ; passing null is equivalent to + * calling findL2Key with the attributes and storing in the returned value. + * + * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2 + * key and only care about grouping can pass a unique ID here like the ones + * generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low + * relevance of such a network will lead to it being evicted soon if it's not + * refreshed. Use findL2Key to try and find a similar L2Key to these attributes. + * @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. + */ + void storeNetworkAttributes(String l2Key, in NetworkAttributesParcelable attributes, + IOnStatusListener listener); + + /** + * Store a binary blob associated with an L2 key and a name. + * + * @param l2Key The L2 key for this network. + * @param clientId The ID of the client. + * @param name The name of this data. + * @param data The data to store. + * @param listener A listener 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 or failure. + */ + void storeBlob(String l2Key, String clientId, String name, in Blob data, + IOnStatusListener listener); + + /** + * Returns the best L2 key associated with the attributes. + * + * This will find a record that would be in the same group as the passed attributes. This is + * useful to choose the key for storing a sample or private data when the L2 key is not known. + * If multiple records are group-close to these attributes, the closest match is returned. + * If multiple records have the same closeness, the one with the smaller (unicode codepoint + * order) L2 key is returned. + * If no record matches these attributes, null is returned. + * + * @param attributes The attributes of the network to find. + * @param listener The listener that will be invoked to return the answer. + * @return (through the listener) The L2 key if one matched, or null. + */ + void findL2Key(in NetworkAttributesParcelable attributes, IOnL2KeyResponseListener listener); + + /** + * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point + * to the same L3 network. Group-closeness is used to determine this. + * + * @param l2Key1 The key for the first network. + * @param l2Key2 The key for the second network. + * @param listener The listener that will be invoked to return the answer. + * @return (through the listener) A SameL3NetworkResponse containing the answer and confidence. + */ + void isSameNetwork(String l2Key1, String l2Key2, IOnSameL3NetworkResponseListener listener); + + /** + * Retrieve the network attributes for a key. + * If no record is present for this key, this will return null attributes. + * + * @param l2Key The key of the network to query. + * @param listener The listener that will be invoked to return the answer. + * @return (through the listener) The network attributes and the L2 key associated with + * the query. + */ + void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrievedListener listener); + + /** + * Retrieve previously stored private data. + * If no data was stored for this L2 key and name this will return null. + * + * @param l2Key The L2 key. + * @param clientId The id of the client that stored this data. + * @param name The name of the data. + * @param listener The listener that will be invoked to return the answer. + * @return (through the listener) The private data (or null), with the L2 key + * and the name of the data associated with the query. + */ + void retrieveBlob(String l2Key, String clientId, String name, + IOnBlobRetrievedListener listener); + + /** + * Delete all data because a factory reset operation is in progress. + */ + void factoryReset(); +} diff --git a/common/networkstackclient/src/android/net/IIpMemoryStoreCallbacks.aidl b/common/networkstackclient/src/android/net/IIpMemoryStoreCallbacks.aidl new file mode 100644 index 0000000..53108db --- /dev/null +++ b/common/networkstackclient/src/android/net/IIpMemoryStoreCallbacks.aidl @@ -0,0 +1,24 @@ +/* + * 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; + +import android.net.IIpMemoryStore; + +/** {@hide} */ +oneway interface IIpMemoryStoreCallbacks { + void onIpMemoryStoreFetched(in IIpMemoryStore ipMemoryStore); +} diff --git a/common/networkstackclient/src/android/net/INetworkMonitor.aidl b/common/networkstackclient/src/android/net/INetworkMonitor.aidl new file mode 100644 index 0000000..3fc81a3 --- /dev/null +++ b/common/networkstackclient/src/android/net/INetworkMonitor.aidl @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2018, 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 perNmissions and + * limitations under the License. + */ +package android.net; + +import android.net.LinkProperties; +import android.net.NetworkCapabilities; +import android.net.PrivateDnsConfigParcel; + +/** @hide */ +oneway interface INetworkMonitor { + // After a network has been tested this result can be sent with EVENT_NETWORK_TESTED. + // The network should be used as a default internet connection. It was found to be: + // 1. a functioning network providing internet access, or + // 2. a captive portal and the user decided to use it as is. + const int NETWORK_TEST_RESULT_VALID = 0; + + // After a network has been tested this result can be sent with EVENT_NETWORK_TESTED. + // The network should not be used as a default internet connection. It was found to be: + // 1. a captive portal and the user is prompted to sign-in, or + // 2. a captive portal and the user did not want to use it, or + // 3. a broken network (e.g. DNS failed, connect failed, HTTP request failed). + const int NETWORK_TEST_RESULT_INVALID = 1; + + // After a network has been tested, this result can be sent with EVENT_NETWORK_TESTED. + // The network may be used as a default internet connection, but it was found to be a partial + // connectivity network which can get the pass result for http probe but get the failed result + // for https probe. + const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2; + + // Network validation flags indicate probe result and types. If no NETWORK_VALIDATION_RESULT_* + // are set, then it's equal to NETWORK_TEST_RESULT_INVALID. If NETWORK_VALIDATION_RESULT_VALID + // is set, then the network validates and equal to NETWORK_TEST_RESULT_VALID. If + // NETWORK_VALIDATION_RESULT_PARTIAL is set, then the network has partial connectivity which + // is equal to NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY. NETWORK_VALIDATION_PROBE_* is set + // when the specific probe result of the network is resolved. + const int NETWORK_VALIDATION_RESULT_VALID = 0x01; + const int NETWORK_VALIDATION_RESULT_PARTIAL = 0x02; + const int NETWORK_VALIDATION_PROBE_DNS = 0x04; + const int NETWORK_VALIDATION_PROBE_HTTP = 0x08; + const int NETWORK_VALIDATION_PROBE_HTTPS = 0x10; + const int NETWORK_VALIDATION_PROBE_FALLBACK = 0x20; + const int NETWORK_VALIDATION_PROBE_PRIVDNS = 0x40; + + void start(); + void launchCaptivePortalApp(); + void notifyCaptivePortalAppFinished(int response); + void setAcceptPartialConnectivity(); + void forceReevaluation(int uid); + void notifyPrivateDnsChanged(in PrivateDnsConfigParcel config); + void notifyDnsResponse(int returnCode); + void notifyNetworkConnected(in LinkProperties lp, in NetworkCapabilities nc); + void notifyNetworkDisconnected(); + void notifyLinkPropertiesChanged(in LinkProperties lp); + void notifyNetworkCapabilitiesChanged(in NetworkCapabilities nc); +} diff --git a/common/networkstackclient/src/android/net/INetworkMonitorCallbacks.aidl b/common/networkstackclient/src/android/net/INetworkMonitorCallbacks.aidl new file mode 100644 index 0000000..2c61511 --- /dev/null +++ b/common/networkstackclient/src/android/net/INetworkMonitorCallbacks.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 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; + +import android.net.INetworkMonitor; +import android.net.PrivateDnsConfigParcel; + +/** @hide */ +oneway interface INetworkMonitorCallbacks { + void onNetworkMonitorCreated(in INetworkMonitor networkMonitor); + void notifyNetworkTested(int testResult, @nullable String redirectUrl); + void notifyPrivateDnsConfigResolved(in PrivateDnsConfigParcel config); + void showProvisioningNotification(String action, String packageName); + void hideProvisioningNotification(); +}
\ No newline at end of file diff --git a/common/networkstackclient/src/android/net/INetworkStackConnector.aidl b/common/networkstackclient/src/android/net/INetworkStackConnector.aidl new file mode 100644 index 0000000..3751c36 --- /dev/null +++ b/common/networkstackclient/src/android/net/INetworkStackConnector.aidl @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018, 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 perNmissions and + * limitations under the License. + */ +package android.net; + +import android.net.IIpMemoryStoreCallbacks; +import android.net.INetworkMonitorCallbacks; +import android.net.Network; +import android.net.dhcp.DhcpServingParamsParcel; +import android.net.dhcp.IDhcpServerCallbacks; +import android.net.ip.IIpClientCallbacks; + +/** @hide */ +oneway interface INetworkStackConnector { + void makeDhcpServer(in String ifName, in DhcpServingParamsParcel params, + in IDhcpServerCallbacks cb); + void makeNetworkMonitor(in Network network, String name, in INetworkMonitorCallbacks cb); + void makeIpClient(in String ifName, in IIpClientCallbacks callbacks); + void fetchIpMemoryStore(in IIpMemoryStoreCallbacks cb); +} diff --git a/common/networkstackclient/src/android/net/INetworkStackStatusCallback.aidl b/common/networkstackclient/src/android/net/INetworkStackStatusCallback.aidl new file mode 100644 index 0000000..51032d8 --- /dev/null +++ b/common/networkstackclient/src/android/net/INetworkStackStatusCallback.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2018 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; + +/** @hide */ +oneway interface INetworkStackStatusCallback { + void onStatusAvailable(int statusCode); +}
\ No newline at end of file diff --git a/common/networkstackclient/src/android/net/InitialConfigurationParcelable.aidl b/common/networkstackclient/src/android/net/InitialConfigurationParcelable.aidl new file mode 100644 index 0000000..3fa88c3 --- /dev/null +++ b/common/networkstackclient/src/android/net/InitialConfigurationParcelable.aidl @@ -0,0 +1,27 @@ +/* + * 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; + +import android.net.IpPrefix; +import android.net.LinkAddress; + +parcelable InitialConfigurationParcelable { + LinkAddress[] ipAddresses; + IpPrefix[] directlyConnectedRoutes; + String[] dnsServers; + String gateway; +}
\ No newline at end of file diff --git a/common/networkstackclient/src/android/net/IpMemoryStoreClient.java b/common/networkstackclient/src/android/net/IpMemoryStoreClient.java new file mode 100644 index 0000000..014b528 --- /dev/null +++ b/common/networkstackclient/src/android/net/IpMemoryStoreClient.java @@ -0,0 +1,227 @@ +/* + * 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.net.ipmemorystore.Blob; +import android.net.ipmemorystore.NetworkAttributes; +import android.net.ipmemorystore.OnBlobRetrievedListener; +import android.net.ipmemorystore.OnL2KeyResponseListener; +import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener; +import android.net.ipmemorystore.OnSameL3NetworkResponseListener; +import android.net.ipmemorystore.OnStatusListener; +import android.net.ipmemorystore.Status; +import android.os.RemoteException; +import android.util.Log; + +import java.util.concurrent.ExecutionException; +import java.util.function.Consumer; + +/** + * service used to communicate with the ip memory store service in network stack, + * which is running in a separate module. + * @hide + */ +public abstract class IpMemoryStoreClient { + private static final String TAG = IpMemoryStoreClient.class.getSimpleName(); + private final Context mContext; + + public IpMemoryStoreClient(@NonNull final Context context) { + if (context == null) throw new IllegalArgumentException("missing context"); + mContext = context; + } + + protected abstract void runWhenServiceReady(Consumer<IIpMemoryStore> cb) + throws ExecutionException; + + @FunctionalInterface + private interface ThrowingRunnable { + void run() throws RemoteException; + } + + private void ignoringRemoteException(ThrowingRunnable r) { + ignoringRemoteException("Failed to execute remote procedure call", r); + } + + private void ignoringRemoteException(String message, ThrowingRunnable r) { + try { + r.run(); + } catch (RemoteException e) { + Log.e(TAG, message, e); + } + } + + /** + * Store network attributes for a given L2 key. + * If L2Key is null, choose automatically from the attributes ; passing null is equivalent to + * calling findL2Key with the attributes and storing in the returned value. + * + * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2 + * key and only care about grouping can pass a unique ID here like the ones + * generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low + * relevance of such a network will lead to it being evicted soon if it's not + * refreshed. Use findL2Key to try and find a similar L2Key to these attributes. + * @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. + * Through the listener, returns the L2 key. This is useful if the L2 key was not specified. + * If the call failed, the L2 key will be null. + */ + public void storeNetworkAttributes(@NonNull final String l2Key, + @NonNull final NetworkAttributes attributes, + @Nullable final OnStatusListener listener) { + try { + runWhenServiceReady(service -> ignoringRemoteException( + () -> service.storeNetworkAttributes(l2Key, attributes.toParcelable(), + OnStatusListener.toAIDL(listener)))); + } catch (ExecutionException m) { + ignoringRemoteException("Error storing network attributes", + () -> listener.onComplete(new Status(Status.ERROR_UNKNOWN))); + } + } + + /** + * Store a binary blob associated with an L2 key and a name. + * + * @param l2Key The L2 key for this network. + * @param clientId The ID of the client. + * @param name The name of this data. + * @param data The data to store. + * @param listener A listener to inform of the completion of this call, or null if the client + * is not interested in learning about success/failure. + * Through the listener, returns a status to indicate success or failure. + */ + public void storeBlob(@NonNull final String l2Key, @NonNull final String clientId, + @NonNull final String name, @NonNull final Blob data, + @Nullable final OnStatusListener listener) { + try { + runWhenServiceReady(service -> ignoringRemoteException( + () -> service.storeBlob(l2Key, clientId, name, data, + OnStatusListener.toAIDL(listener)))); + } catch (ExecutionException m) { + ignoringRemoteException("Error storing blob", + () -> listener.onComplete(new Status(Status.ERROR_UNKNOWN))); + } + } + + /** + * Returns the best L2 key associated with the attributes. + * + * This will find a record that would be in the same group as the passed attributes. This is + * useful to choose the key for storing a sample or private data when the L2 key is not known. + * If multiple records are group-close to these attributes, the closest match is returned. + * If multiple records have the same closeness, the one with the smaller (unicode codepoint + * order) L2 key is returned. + * If no record matches these attributes, null is returned. + * + * @param attributes The attributes of the network to find. + * @param listener The listener that will be invoked to return the answer. + * Through the listener, returns the L2 key if one matched, or null. + */ + public void findL2Key(@NonNull final NetworkAttributes attributes, + @NonNull final OnL2KeyResponseListener listener) { + try { + runWhenServiceReady(service -> ignoringRemoteException( + () -> service.findL2Key(attributes.toParcelable(), + OnL2KeyResponseListener.toAIDL(listener)))); + } catch (ExecutionException m) { + ignoringRemoteException("Error finding L2 Key", + () -> listener.onL2KeyResponse(new Status(Status.ERROR_UNKNOWN), null)); + } + } + + /** + * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point + * to the same L3 network. Group-closeness is used to determine this. + * + * @param l2Key1 The key for the first network. + * @param l2Key2 The key for the second network. + * @param listener The listener that will be invoked to return the answer. + * Through the listener, a SameL3NetworkResponse containing the answer and confidence. + */ + public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2, + @NonNull final OnSameL3NetworkResponseListener listener) { + try { + runWhenServiceReady(service -> ignoringRemoteException( + () -> service.isSameNetwork(l2Key1, l2Key2, + OnSameL3NetworkResponseListener.toAIDL(listener)))); + } catch (ExecutionException m) { + ignoringRemoteException("Error checking for network sameness", + () -> listener.onSameL3NetworkResponse(new Status(Status.ERROR_UNKNOWN), null)); + } + } + + /** + * Retrieve the network attributes for a key. + * If no record is present for this key, this will return null attributes. + * + * @param l2Key The key of the network to query. + * @param listener The listener that will be invoked to return the answer. + * Through the listener, returns the network attributes and the L2 key associated with + * the query. + */ + public void retrieveNetworkAttributes(@NonNull final String l2Key, + @NonNull final OnNetworkAttributesRetrievedListener listener) { + try { + runWhenServiceReady(service -> ignoringRemoteException( + () -> service.retrieveNetworkAttributes(l2Key, + OnNetworkAttributesRetrievedListener.toAIDL(listener)))); + } catch (ExecutionException m) { + ignoringRemoteException("Error retrieving network attributes", + () -> listener.onNetworkAttributesRetrieved(new Status(Status.ERROR_UNKNOWN), + null, null)); + } + } + + /** + * Retrieve previously stored private data. + * If no data was stored for this L2 key and name this will return null. + * + * @param l2Key The L2 key. + * @param clientId The id of the client that stored this data. + * @param name The name of the data. + * @param listener The listener that will be invoked to return the answer. + * Through the listener, returns the private data (or null), with the L2 key + * and the name of the data associated with the query. + */ + public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId, + @NonNull final String name, @NonNull final OnBlobRetrievedListener listener) { + try { + runWhenServiceReady(service -> ignoringRemoteException( + () -> service.retrieveBlob(l2Key, clientId, name, + OnBlobRetrievedListener.toAIDL(listener)))); + } catch (ExecutionException m) { + ignoringRemoteException("Error retrieving blob", + () -> listener.onBlobRetrieved(new Status(Status.ERROR_UNKNOWN), + null, null, null)); + } + } + + /** + * Wipe the data in the database upon network factory reset. + */ + public void factoryReset() { + try { + runWhenServiceReady(service -> ignoringRemoteException( + () -> service.factoryReset())); + } catch (ExecutionException m) { + Log.e(TAG, "Error executing factory reset", m); + } + } +} diff --git a/common/networkstackclient/src/android/net/NattKeepalivePacketDataParcelable.aidl b/common/networkstackclient/src/android/net/NattKeepalivePacketDataParcelable.aidl new file mode 100644 index 0000000..6f006d4 --- /dev/null +++ b/common/networkstackclient/src/android/net/NattKeepalivePacketDataParcelable.aidl @@ -0,0 +1,25 @@ +/* + * 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; + +parcelable NattKeepalivePacketDataParcelable { + byte[] srcAddress; + int srcPort; + byte[] dstAddress; + int dstPort; +} + diff --git a/common/networkstackclient/src/android/net/PrivateDnsConfigParcel.aidl b/common/networkstackclient/src/android/net/PrivateDnsConfigParcel.aidl new file mode 100644 index 0000000..b52fce6 --- /dev/null +++ b/common/networkstackclient/src/android/net/PrivateDnsConfigParcel.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2018 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; + +parcelable PrivateDnsConfigParcel { + String hostname; + String[] ips; +} diff --git a/common/networkstackclient/src/android/net/ProvisioningConfigurationParcelable.aidl b/common/networkstackclient/src/android/net/ProvisioningConfigurationParcelable.aidl new file mode 100644 index 0000000..99606fb --- /dev/null +++ b/common/networkstackclient/src/android/net/ProvisioningConfigurationParcelable.aidl @@ -0,0 +1,38 @@ +/* +** +** 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; + +import android.net.InitialConfigurationParcelable; +import android.net.Network; +import android.net.StaticIpConfiguration; +import android.net.apf.ApfCapabilities; + +parcelable ProvisioningConfigurationParcelable { + boolean enableIPv4; + boolean enableIPv6; + boolean usingMultinetworkPolicyTracker; + boolean usingIpReachabilityMonitor; + int requestedPreDhcpActionMs; + InitialConfigurationParcelable initialConfig; + StaticIpConfiguration staticIpConfig; + ApfCapabilities apfCapabilities; + int provisioningTimeoutMs; + int ipv6AddrGenMode; + Network network; + String displayName; +} diff --git a/common/networkstackclient/src/android/net/TcpKeepalivePacketDataParcelable.aidl b/common/networkstackclient/src/android/net/TcpKeepalivePacketDataParcelable.aidl new file mode 100644 index 0000000..e25168d --- /dev/null +++ b/common/networkstackclient/src/android/net/TcpKeepalivePacketDataParcelable.aidl @@ -0,0 +1,30 @@ +/* + * 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; + +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/src/android/net/dhcp/DhcpServingParamsParcel.aidl b/common/networkstackclient/src/android/net/dhcp/DhcpServingParamsParcel.aidl new file mode 100644 index 0000000..7b8b9ee --- /dev/null +++ b/common/networkstackclient/src/android/net/dhcp/DhcpServingParamsParcel.aidl @@ -0,0 +1,30 @@ +/** + * + * Copyright (C) 2018 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.dhcp; + +parcelable DhcpServingParamsParcel { + int serverAddr; + int serverAddrPrefixLength; + int[] defaultRouters; + int[] dnsServers; + int[] excludedAddrs; + long dhcpLeaseTimeSecs; + int linkMtu; + boolean metered; +} + diff --git a/common/networkstackclient/src/android/net/dhcp/IDhcpServer.aidl b/common/networkstackclient/src/android/net/dhcp/IDhcpServer.aidl new file mode 100644 index 0000000..559433b --- /dev/null +++ b/common/networkstackclient/src/android/net/dhcp/IDhcpServer.aidl @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018, 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 perNmissions and + * limitations under the License. + */ + +package android.net.dhcp; + +import android.net.INetworkStackStatusCallback; +import android.net.dhcp.DhcpServingParamsParcel; + +/** @hide */ +oneway interface IDhcpServer { + const int STATUS_UNKNOWN = 0; + const int STATUS_SUCCESS = 1; + const int STATUS_INVALID_ARGUMENT = 2; + const int STATUS_UNKNOWN_ERROR = 3; + + void start(in INetworkStackStatusCallback cb); + void updateParams(in DhcpServingParamsParcel params, in INetworkStackStatusCallback cb); + void stop(in INetworkStackStatusCallback cb); +} diff --git a/common/networkstackclient/src/android/net/dhcp/IDhcpServerCallbacks.aidl b/common/networkstackclient/src/android/net/dhcp/IDhcpServerCallbacks.aidl new file mode 100644 index 0000000..7ab4dcd --- /dev/null +++ b/common/networkstackclient/src/android/net/dhcp/IDhcpServerCallbacks.aidl @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018, 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 perNmissions and + * limitations under the License. + */ + +package android.net.dhcp; + +import android.net.dhcp.IDhcpServer; + +/** @hide */ +oneway interface IDhcpServerCallbacks { + void onDhcpServerCreated(int statusCode, in IDhcpServer server); +} diff --git a/common/networkstackclient/src/android/net/ip/IIpClient.aidl b/common/networkstackclient/src/android/net/ip/IIpClient.aidl new file mode 100644 index 0000000..9989c52 --- /dev/null +++ b/common/networkstackclient/src/android/net/ip/IIpClient.aidl @@ -0,0 +1,38 @@ +/** + * 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 perNmissions and + * limitations under the License. + */ +package android.net.ip; + +import android.net.ProxyInfo; +import android.net.ProvisioningConfigurationParcelable; +import android.net.NattKeepalivePacketDataParcelable; +import android.net.TcpKeepalivePacketDataParcelable; + +/** @hide */ +oneway interface IIpClient { + void completedPreDhcpAction(); + void confirmConfiguration(); + void readPacketFilterComplete(in byte[] data); + void shutdown(); + void startProvisioning(in ProvisioningConfigurationParcelable req); + void stop(); + void setTcpBufferSizes(in String tcpBufferSizes); + void setHttpProxy(in ProxyInfo proxyInfo); + void setMulticastFilter(boolean enabled); + void addKeepalivePacketFilter(int slot, in TcpKeepalivePacketDataParcelable pkt); + void removeKeepalivePacketFilter(int slot); + void setL2KeyAndGroupHint(in String l2Key, in String groupHint); + void addNattKeepalivePacketFilter(int slot, in NattKeepalivePacketDataParcelable pkt); +} diff --git a/common/networkstackclient/src/android/net/ip/IIpClientCallbacks.aidl b/common/networkstackclient/src/android/net/ip/IIpClientCallbacks.aidl new file mode 100644 index 0000000..3681416 --- /dev/null +++ b/common/networkstackclient/src/android/net/ip/IIpClientCallbacks.aidl @@ -0,0 +1,66 @@ +/** + * 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 perNmissions and + * limitations under the License. + */ +package android.net.ip; + +import android.net.LinkProperties; +import android.net.ip.IIpClient; +import android.net.DhcpResultsParcelable; + +/** @hide */ +oneway interface IIpClientCallbacks { + void onIpClientCreated(in IIpClient ipClient); + + void onPreDhcpAction(); + void onPostDhcpAction(); + + // This is purely advisory and not an indication of provisioning + // success or failure. This is only here for callers that want to + // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress). + // DHCPv4 or static IPv4 configuration failure or success can be + // determined by whether or not the passed-in DhcpResults object is + // null or not. + void onNewDhcpResults(in DhcpResultsParcelable dhcpResults); + + void onProvisioningSuccess(in LinkProperties newLp); + void onProvisioningFailure(in LinkProperties newLp); + + // Invoked on LinkProperties changes. + void onLinkPropertiesChange(in LinkProperties newLp); + + // Called when the internal IpReachabilityMonitor (if enabled) has + // detected the loss of a critical number of required neighbors. + void onReachabilityLost(in String logMsg); + + // Called when the IpClient state machine terminates. + void onQuit(); + + // Install an APF program to filter incoming packets. + void installPacketFilter(in byte[] filter); + + // Asynchronously read back the APF program & data buffer from the wifi driver. + // Due to Wifi HAL limitations, the current implementation only supports dumping the entire + // buffer. In response to this request, the driver returns the data buffer asynchronously + // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message. + void startReadPacketFilter(); + + // If multicast filtering cannot be accomplished with APF, this function will be called to + // actuate multicast filtering using another means. + void setFallbackMulticastFilter(boolean enabled); + + // Enabled/disable Neighbor Discover offload functionality. This is + // called, for example, whenever 464xlat is being started or stopped. + void setNeighborDiscoveryOffload(boolean enable); +}
\ No newline at end of file diff --git a/common/networkstackclient/src/android/net/ipmemorystore/Blob.aidl b/common/networkstackclient/src/android/net/ipmemorystore/Blob.aidl new file mode 100644 index 0000000..9dbef11 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/Blob.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2018 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; + +/** + * A blob of data opaque to the memory store. The client mutates this at its own risk, + * and it is strongly suggested to never do it at all and treat this as immutable. + * {@hide} + */ +parcelable Blob { + byte[] data; +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/common/networkstackclient/src/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl new file mode 100644 index 0000000..4926feb --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 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.Blob; +import android.net.ipmemorystore.StatusParcelable; + +/** {@hide} */ +oneway interface IOnBlobRetrievedListener { + /** + * Private data was retrieved for the L2 key and name specified. + * Note this does not return the client ID, as clients are expected to only ever use one ID. + */ + void onBlobRetrieved(in StatusParcelable status, in String l2Key, in String name, + in Blob data); +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/common/networkstackclient/src/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl new file mode 100644 index 0000000..dea0cc4 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 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 IOnL2KeyResponseListener { + /** + * The operation completed with the specified L2 key. + */ + void onL2KeyResponse(in StatusParcelable status, in String l2Key); +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/common/networkstackclient/src/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl new file mode 100644 index 0000000..870e217 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 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.NetworkAttributesParcelable; +import android.net.ipmemorystore.StatusParcelable; + +/** {@hide} */ +oneway interface IOnNetworkAttributesRetrievedListener { + /** + * Network attributes were fetched for the specified L2 key. While the L2 key will never + * be null, the attributes may be if no data is stored about this L2 key. + */ + void onNetworkAttributesRetrieved(in StatusParcelable status, in String l2Key, + in NetworkAttributesParcelable attributes); +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/common/networkstackclient/src/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl new file mode 100644 index 0000000..b8ccfb9 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 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.SameL3NetworkResponseParcelable; +import android.net.ipmemorystore.StatusParcelable; + +/** {@hide} */ +oneway interface IOnSameL3NetworkResponseListener { + /** + * The memory store has come up with the answer to a query that was sent. + */ + void onSameL3NetworkResponse(in StatusParcelable status, + in SameL3NetworkResponseParcelable response); +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/IOnStatusListener.aidl b/common/networkstackclient/src/android/net/ipmemorystore/IOnStatusListener.aidl new file mode 100644 index 0000000..5d07504 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/IOnStatusListener.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 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 IOnStatusListener { + /** + * The operation has completed with the specified status. + */ + void onComplete(in StatusParcelable status); +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java new file mode 100644 index 0000000..818515a --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributes.java @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2018 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; + +import com.android.internal.annotations.VisibleForTesting; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.StringJoiner; + +/** + * A POD object to represent attributes of a single L2 network entry. + * @hide + */ +public class NetworkAttributes { + private static final boolean DBG = true; + + // Weight cutoff for grouping. To group, a similarity score is computed with the following + // algorithm : if both fields are non-null and equals() then add their assigned weight, else if + // both are null then add a portion of their assigned weight (see NULL_MATCH_WEIGHT), + // otherwise add nothing. + // As a guideline, this should be something like 60~75% of the total weights in this class. The + // design states "in essence a reader should imagine that if two important columns don't match, + // or one important and several unimportant columns don't match then the two records are + // considered a different group". + private static final float TOTAL_WEIGHT_CUTOFF = 520.0f; + // The portion of the weight that is earned when scoring group-sameness by having both columns + // being null. This is because some networks rightfully don't have some attributes (e.g. a + // V6-only network won't have an assigned V4 address) and both being null should count for + // something, but attributes may also be null just because data is unavailable. + private static final float NULL_MATCH_WEIGHT = 0.25f; + + // The v4 address that was assigned to this device the last time it joined this network. + // This typically comes from DHCP but could be something else like static configuration. + // This does not apply to IPv6. + // TODO : add a list of v6 prefixes for the v6 case. + @Nullable + public final Inet4Address assignedV4Address; + private static final float WEIGHT_ASSIGNEDV4ADDR = 300.0f; + + // The lease expiry timestamp of v4 address allocated from DHCP server, in milliseconds. + @Nullable + public final Long assignedV4AddressExpiry; + // lease expiry doesn't imply any correlation between "the same lease expiry value" and "the + // 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. + @Nullable + public final String groupHint; + private static final float WEIGHT_GROUPHINT = 300.0f; + + // The list of DNS server addresses. + @Nullable + public final List<InetAddress> dnsAddresses; + private static final float WEIGHT_DNSADDRESSES = 200.0f; + + // The mtu on this network. + @Nullable + public final Integer mtu; + private static final float WEIGHT_MTU = 50.0f; + + // The sum of all weights in this class. Tests ensure that this stays equal to the total of + // all weights. + /** @hide */ + @VisibleForTesting + public static final float TOTAL_WEIGHT = WEIGHT_ASSIGNEDV4ADDR + + WEIGHT_ASSIGNEDV4ADDREXPIRY + + WEIGHT_GROUPHINT + + WEIGHT_DNSADDRESSES + + WEIGHT_MTU; + + /** @hide */ + @VisibleForTesting + public NetworkAttributes( + @Nullable final Inet4Address assignedV4Address, + @Nullable final Long assignedV4AddressExpiry, + @Nullable final String groupHint, + @Nullable final List<InetAddress> dnsAddresses, + @Nullable final Integer mtu) { + if (mtu != null && mtu < 0) throw new IllegalArgumentException("MTU can't be negative"); + if (assignedV4AddressExpiry != null && assignedV4AddressExpiry <= 0) { + throw new IllegalArgumentException("lease expiry can't be negative or zero"); + } + this.assignedV4Address = assignedV4Address; + this.assignedV4AddressExpiry = assignedV4AddressExpiry; + this.groupHint = groupHint; + this.dnsAddresses = null == dnsAddresses ? null : + Collections.unmodifiableList(new ArrayList<>(dnsAddresses)); + this.mtu = mtu; + } + + @VisibleForTesting + public NetworkAttributes(@NonNull final NetworkAttributesParcelable parcelable) { + // The call to the other constructor must be the first statement of this constructor, + // so everything has to be inline + this((Inet4Address) getByAddressOrNull(parcelable.assignedV4Address), + parcelable.assignedV4AddressExpiry > 0 + ? parcelable.assignedV4AddressExpiry : null, + parcelable.groupHint, + blobArrayToInetAddressList(parcelable.dnsAddresses), + parcelable.mtu >= 0 ? parcelable.mtu : null); + } + + @Nullable + private static InetAddress getByAddressOrNull(@Nullable final byte[] address) { + if (null == address) return null; + try { + return InetAddress.getByAddress(address); + } catch (UnknownHostException e) { + return null; + } + } + + @Nullable + private static List<InetAddress> blobArrayToInetAddressList(@Nullable final Blob[] blobs) { + if (null == blobs) return null; + final ArrayList<InetAddress> list = new ArrayList<>(blobs.length); + for (final Blob b : blobs) { + final InetAddress addr = getByAddressOrNull(b.data); + if (null != addr) list.add(addr); + } + return list; + } + + @Nullable + private static Blob[] inetAddressListToBlobArray(@Nullable final List<InetAddress> addresses) { + if (null == addresses) return null; + final ArrayList<Blob> blobs = new ArrayList<>(); + for (int i = 0; i < addresses.size(); ++i) { + final InetAddress addr = addresses.get(i); + if (null == addr) continue; + final Blob b = new Blob(); + b.data = addr.getAddress(); + blobs.add(b); + } + return blobs.toArray(new Blob[0]); + } + + /** Converts this NetworkAttributes to a parcelable object */ + @NonNull + public NetworkAttributesParcelable toParcelable() { + final NetworkAttributesParcelable parcelable = new NetworkAttributesParcelable(); + parcelable.assignedV4Address = + (null == assignedV4Address) ? null : assignedV4Address.getAddress(); + parcelable.assignedV4AddressExpiry = + (null == assignedV4AddressExpiry) ? 0 : assignedV4AddressExpiry; + parcelable.groupHint = groupHint; + parcelable.dnsAddresses = inetAddressListToBlobArray(dnsAddresses); + parcelable.mtu = (null == mtu) ? -1 : mtu; + return parcelable; + } + + private float samenessContribution(final float weight, + @Nullable final Object o1, @Nullable final Object o2) { + if (null == o1) { + return (null == o2) ? weight * NULL_MATCH_WEIGHT : 0f; + } + return Objects.equals(o1, o2) ? weight : 0f; + } + + /** @hide */ + public float getNetworkGroupSamenessConfidence(@NonNull final NetworkAttributes o) { + final float samenessScore = + samenessContribution(WEIGHT_ASSIGNEDV4ADDR, assignedV4Address, o.assignedV4Address) + + samenessContribution(WEIGHT_ASSIGNEDV4ADDREXPIRY, assignedV4AddressExpiry, + o.assignedV4AddressExpiry) + + samenessContribution(WEIGHT_GROUPHINT, groupHint, o.groupHint) + + 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 + // TOTAL_WEIGHT_CUTOFF should represent 0.5, but there is no requirement that + // TOTAL_WEIGHT_CUTOFF would be half of TOTAL_WEIGHT (indeed, it should not be). + // So scale scores under the cutoff between 0 and 0.5, and the scores over the cutoff + // between 0.5 and 1.0. + if (samenessScore < TOTAL_WEIGHT_CUTOFF) { + return samenessScore / (TOTAL_WEIGHT_CUTOFF * 2); + } else { + return (samenessScore - TOTAL_WEIGHT_CUTOFF) / (TOTAL_WEIGHT - TOTAL_WEIGHT_CUTOFF) / 2 + + 0.5f; + } + } + + /** @hide */ + public static class Builder { + @Nullable + private Inet4Address mAssignedAddress; + @Nullable + private Long mAssignedAddressExpiry; + @Nullable + private String mGroupHint; + @Nullable + private List<InetAddress> mDnsAddresses; + @Nullable + private Integer mMtu; + + /** + * Set the assigned address. + * @param assignedV4Address The assigned address. + * @return This builder. + */ + public Builder setAssignedV4Address(@Nullable final Inet4Address assignedV4Address) { + mAssignedAddress = assignedV4Address; + return this; + } + + /** + * Set the lease expiry timestamp of assigned v4 address. Long.MAX_VALUE is used + * to represent "infinite lease". + * + * @param assignedV4AddressExpiry The lease expiry timestamp of assigned v4 address. + * @return This builder. + */ + public Builder setAssignedV4AddressExpiry( + @Nullable final Long assignedV4AddressExpiry) { + if (null != assignedV4AddressExpiry && assignedV4AddressExpiry <= 0) { + throw new IllegalArgumentException("lease expiry can't be negative or zero"); + } + mAssignedAddressExpiry = assignedV4AddressExpiry; + return this; + } + + /** + * Set the group hint. + * @param groupHint The group hint. + * @return This builder. + */ + public Builder setGroupHint(@Nullable final String groupHint) { + mGroupHint = groupHint; + return this; + } + + /** + * Set the DNS addresses. + * @param dnsAddresses The DNS addresses. + * @return This builder. + */ + public Builder setDnsAddresses(@Nullable final List<InetAddress> dnsAddresses) { + if (DBG && null != dnsAddresses) { + // Parceling code crashes if one of the addresses is null, therefore validate + // them when running in debug. + for (final InetAddress address : dnsAddresses) { + if (null == address) throw new IllegalArgumentException("Null DNS address"); + } + } + this.mDnsAddresses = dnsAddresses; + return this; + } + + /** + * Set the MTU. + * @param mtu The MTU. + * @return This builder. + */ + public Builder setMtu(@Nullable final Integer mtu) { + if (null != mtu && mtu < 0) throw new IllegalArgumentException("MTU can't be negative"); + mMtu = mtu; + return this; + } + + /** + * Return the built NetworkAttributes object. + * @return The built NetworkAttributes object. + */ + public NetworkAttributes build() { + return new NetworkAttributes(mAssignedAddress, mAssignedAddressExpiry, + mGroupHint, mDnsAddresses, mMtu); + } + } + + /** @hide */ + public boolean isEmpty() { + return (null == assignedV4Address) && (null == assignedV4AddressExpiry) + && (null == groupHint) && (null == dnsAddresses) && (null == mtu); + } + + @Override + public boolean equals(@Nullable final Object o) { + if (!(o instanceof NetworkAttributes)) return false; + final NetworkAttributes other = (NetworkAttributes) o; + return Objects.equals(assignedV4Address, other.assignedV4Address) + && Objects.equals(assignedV4AddressExpiry, other.assignedV4AddressExpiry) + && Objects.equals(groupHint, other.groupHint) + && Objects.equals(dnsAddresses, other.dnsAddresses) + && Objects.equals(mtu, other.mtu); + } + + @Override + public int hashCode() { + return Objects.hash(assignedV4Address, assignedV4AddressExpiry, + groupHint, dnsAddresses, mtu); + } + + /** Pretty print */ + @Override + public String toString() { + final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}"); + final ArrayList<String> nullFields = new ArrayList<>(); + + if (null != assignedV4Address) { + resultJoiner.add("assignedV4Addr :"); + resultJoiner.add(assignedV4Address.toString()); + } else { + nullFields.add("assignedV4Addr"); + } + + if (null != assignedV4AddressExpiry) { + resultJoiner.add("assignedV4AddressExpiry :"); + resultJoiner.add(assignedV4AddressExpiry.toString()); + } else { + nullFields.add("assignedV4AddressExpiry"); + } + + if (null != groupHint) { + resultJoiner.add("groupHint :"); + resultJoiner.add(groupHint); + } else { + nullFields.add("groupHint"); + } + + if (null != dnsAddresses) { + resultJoiner.add("dnsAddr : ["); + for (final InetAddress addr : dnsAddresses) { + resultJoiner.add(addr.getHostAddress()); + } + resultJoiner.add("]"); + } else { + nullFields.add("dnsAddr"); + } + + if (null != mtu) { + resultJoiner.add("mtu :"); + resultJoiner.add(mtu.toString()); + } else { + nullFields.add("mtu"); + } + + if (!nullFields.isEmpty()) { + resultJoiner.add("; Null fields : ["); + for (final String field : nullFields) { + resultJoiner.add(field); + } + resultJoiner.add("]"); + } + + return resultJoiner.toString(); + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributesParcelable.aidl new file mode 100644 index 0000000..997eb2b --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/NetworkAttributesParcelable.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 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; + +// Blob[] is used to represent an array of byte[], as structured AIDL does not support arrays +// of arrays. +import android.net.ipmemorystore.Blob; + +/** + * An object to represent attributes of a single L2 network entry. + * See NetworkAttributes.java for a description of each field. The types used in this class + * are structured parcelable types instead of the richer types of the NetworkAttributes object, + * but they have the same purpose. The NetworkAttributes.java file also contains the code + * to convert the richer types to the parcelable types and back. + * @hide + */ +parcelable NetworkAttributesParcelable { + byte[] assignedV4Address; + long assignedV4AddressExpiry; + String groupHint; + Blob[] dnsAddresses; + int mtu; +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/OnBlobRetrievedListener.java b/common/networkstackclient/src/android/net/ipmemorystore/OnBlobRetrievedListener.java new file mode 100644 index 0000000..a17483a --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/OnBlobRetrievedListener.java @@ -0,0 +1,50 @@ +/* + * 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; + +/** + * A listener for the IpMemoryStore to return a blob. + * @hide + */ +public interface OnBlobRetrievedListener { + /** + * The memory store has come up with the answer to a query that was sent. + */ + void onBlobRetrieved(Status status, String l2Key, String name, Blob blob); + + /** Converts this OnBlobRetrievedListener to a parcelable object */ + @NonNull + static IOnBlobRetrievedListener toAIDL(@NonNull final OnBlobRetrievedListener listener) { + return new IOnBlobRetrievedListener.Stub() { + @Override + public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key, + final String name, final Blob blob) { + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob); + } + } + + @Override + public int getInterfaceVersion() { + return this.VERSION; + } + }; + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/OnL2KeyResponseListener.java b/common/networkstackclient/src/android/net/ipmemorystore/OnL2KeyResponseListener.java new file mode 100644 index 0000000..e608aec --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/OnL2KeyResponseListener.java @@ -0,0 +1,50 @@ +/* + * 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; + +/** + * A listener for the IpMemoryStore to return a L2 key. + * @hide + */ +public interface OnL2KeyResponseListener { + /** + * The operation has completed with the specified status. + */ + void onL2KeyResponse(Status status, String l2Key); + + /** Converts this OnL2KeyResponseListener to a parcelable object */ + @NonNull + static IOnL2KeyResponseListener toAIDL(@NonNull final OnL2KeyResponseListener listener) { + return new IOnL2KeyResponseListener.Stub() { + @Override + public void onL2KeyResponse(final StatusParcelable statusParcelable, + final String l2Key) { + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onL2KeyResponse(new Status(statusParcelable), l2Key); + } + } + + @Override + public int getInterfaceVersion() { + return this.VERSION; + } + }; + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/common/networkstackclient/src/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java new file mode 100644 index 0000000..395ad98 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java @@ -0,0 +1,54 @@ +/* + * 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; + +/** + * A listener for the IpMemoryStore to return network attributes. + * @hide + */ +public interface OnNetworkAttributesRetrievedListener { + /** + * The memory store has come up with the answer to a query that was sent. + */ + void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attributes); + + /** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */ + @NonNull + static IOnNetworkAttributesRetrievedListener toAIDL( + @NonNull final OnNetworkAttributesRetrievedListener listener) { + return new IOnNetworkAttributesRetrievedListener.Stub() { + @Override + public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable, + final String l2Key, + final NetworkAttributesParcelable networkAttributesParcelable) { + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onNetworkAttributesRetrieved( + new Status(statusParcelable), l2Key, null == networkAttributesParcelable + ? null : new NetworkAttributes(networkAttributesParcelable)); + } + } + + @Override + public int getInterfaceVersion() { + return this.VERSION; + } + }; + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/common/networkstackclient/src/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java new file mode 100644 index 0000000..67f8da8 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java @@ -0,0 +1,53 @@ +/* + * 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; + +/** + * A listener for the IpMemoryStore to return a response about network sameness. + * @hide + */ +public interface OnSameL3NetworkResponseListener { + /** + * The memory store has come up with the answer to a query that was sent. + */ + void onSameL3NetworkResponse(Status status, SameL3NetworkResponse response); + + /** Converts this OnSameL3NetworkResponseListener to a parcelable object */ + @NonNull + static IOnSameL3NetworkResponseListener toAIDL( + @NonNull final OnSameL3NetworkResponseListener listener) { + return new IOnSameL3NetworkResponseListener.Stub() { + @Override + public void onSameL3NetworkResponse(final StatusParcelable statusParcelable, + final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) { + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onSameL3NetworkResponse( + new Status(statusParcelable), + new SameL3NetworkResponse(sameL3NetworkResponseParcelable)); + } + } + + @Override + public int getInterfaceVersion() { + return this.VERSION; + } + }; + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/OnStatusListener.java b/common/networkstackclient/src/android/net/ipmemorystore/OnStatusListener.java new file mode 100644 index 0000000..4262efd --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/OnStatusListener.java @@ -0,0 +1,49 @@ +/* + * 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 OnStatusListener { + /** + * The operation has completed with the specified status. + */ + void onComplete(Status status); + + /** Converts this OnStatusListener to a parcelable object */ + @NonNull + static IOnStatusListener toAIDL(@Nullable final OnStatusListener listener) { + return new IOnStatusListener.Stub() { + @Override + public void onComplete(final StatusParcelable statusParcelable) { + if (null != listener) { + listener.onComplete(new Status(statusParcelable)); + } + } + + @Override + public int getInterfaceVersion() { + return this.VERSION; + } + }; + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/SameL3NetworkResponse.java b/common/networkstackclient/src/android/net/ipmemorystore/SameL3NetworkResponse.java new file mode 100644 index 0000000..291aca8 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/SameL3NetworkResponse.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2018 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.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; + +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * An object representing the answer to a query whether two given L2 networks represent the + * same L3 network. Parcels as a SameL3NetworkResponseParceled object. + * @hide + */ +public class SameL3NetworkResponse { + @IntDef(prefix = "NETWORK_", + value = {NETWORK_SAME, NETWORK_DIFFERENT, NETWORK_NEVER_CONNECTED}) + @Retention(RetentionPolicy.SOURCE) + public @interface NetworkSameness {} + + /** + * Both L2 networks represent the same L3 network. + */ + public static final int NETWORK_SAME = 1; + + /** + * The two L2 networks represent a different L3 network. + */ + public static final int NETWORK_DIFFERENT = 2; + + /** + * The device has never connected to at least one of these two L2 networks, or data + * has been wiped. Therefore the device has never seen the L3 network behind at least + * one of these two L2 networks, and can't evaluate whether it's the same as the other. + */ + public static final int NETWORK_NEVER_CONNECTED = 3; + + /** + * The first L2 key specified in the query. + */ + @NonNull + public final String l2Key1; + + /** + * The second L2 key specified in the query. + */ + @NonNull + public final String l2Key2; + + /** + * A confidence value indicating whether the two L2 networks represent the same L3 network. + * + * If both L2 networks were known, this value will be between 0.0 and 1.0, with 0.0 + * representing complete confidence that the given L2 networks represent a different + * L3 network, and 1.0 representing complete confidence that the given L2 networks + * represent the same L3 network. + * If at least one of the L2 networks was not known, this value will be outside of the + * 0.0~1.0 range. + * + * Most apps should not be interested in this, and are encouraged to use the collapsing + * {@link #getNetworkSameness()} function below. + */ + public final float confidence; + + /** + * @return whether the two L2 networks represent the same L3 network. Either + * {@code NETWORK_SAME}, {@code NETWORK_DIFFERENT} or {@code NETWORK_NEVER_CONNECTED}. + */ + @NetworkSameness + public final int getNetworkSameness() { + if (confidence > 1.0 || confidence < 0.0) return NETWORK_NEVER_CONNECTED; + return confidence > 0.5 ? NETWORK_SAME : NETWORK_DIFFERENT; + } + + /** @hide */ + public SameL3NetworkResponse(@NonNull final String l2Key1, @NonNull final String l2Key2, + final float confidence) { + this.l2Key1 = l2Key1; + this.l2Key2 = l2Key2; + this.confidence = confidence; + } + + /** Builds a SameL3NetworkResponse from a parcelable object */ + @VisibleForTesting + public SameL3NetworkResponse(@NonNull final SameL3NetworkResponseParcelable parceled) { + this(parceled.l2Key1, parceled.l2Key2, parceled.confidence); + } + + /** Converts this SameL3NetworkResponse to a parcelable object */ + @NonNull + public SameL3NetworkResponseParcelable toParcelable() { + final SameL3NetworkResponseParcelable parcelable = new SameL3NetworkResponseParcelable(); + parcelable.l2Key1 = l2Key1; + parcelable.l2Key2 = l2Key2; + parcelable.confidence = confidence; + return parcelable; + } + + // Note key1 and key2 have to match each other for this to return true. If + // key1 matches o.key2 and the other way around this returns false. + @Override + public boolean equals(@Nullable final Object o) { + if (!(o instanceof SameL3NetworkResponse)) return false; + final SameL3NetworkResponse other = (SameL3NetworkResponse) o; + return l2Key1.equals(other.l2Key1) && l2Key2.equals(other.l2Key2) + && confidence == other.confidence; + } + + @Override + public int hashCode() { + return Objects.hash(l2Key1, l2Key2, confidence); + } + + @Override + /** Pretty print */ + public String toString() { + switch (getNetworkSameness()) { + case NETWORK_SAME: + return "\"" + l2Key1 + "\" same L3 network as \"" + l2Key2 + "\""; + case NETWORK_DIFFERENT: + return "\"" + l2Key1 + "\" different L3 network from \"" + l2Key2 + "\""; + case NETWORK_NEVER_CONNECTED: + return "\"" + l2Key1 + "\" can't be tested against \"" + l2Key2 + "\""; + default: + return "Buggy sameness value ? \"" + l2Key1 + "\", \"" + l2Key2 + "\""; + } + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/common/networkstackclient/src/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl new file mode 100644 index 0000000..7196699 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2018 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; + +/** {@hide} */ +parcelable SameL3NetworkResponseParcelable { + String l2Key1; + String l2Key2; + float confidence; +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/Status.java b/common/networkstackclient/src/android/net/ipmemorystore/Status.java new file mode 100644 index 0000000..13242c0 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/Status.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2018 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 com.android.internal.annotations.VisibleForTesting; + +/** + * A parcelable status representing the result of an operation. + * Parcels as StatusParceled. + * @hide + */ +public class Status { + public static final int SUCCESS = 0; + + public static final int ERROR_GENERIC = -1; + public static final int ERROR_ILLEGAL_ARGUMENT = -2; + public static final int ERROR_DATABASE_CANNOT_BE_OPENED = -3; + public static final int ERROR_STORAGE = -4; + public static final int ERROR_UNKNOWN = -5; + + public final int resultCode; + + public Status(final int resultCode) { + this.resultCode = resultCode; + } + + @VisibleForTesting + public Status(@NonNull final StatusParcelable parcelable) { + this(parcelable.resultCode); + } + + /** Converts this Status to a parcelable object */ + @NonNull + public StatusParcelable toParcelable() { + final StatusParcelable parcelable = new StatusParcelable(); + parcelable.resultCode = resultCode; + return parcelable; + } + + public boolean isSuccess() { + return SUCCESS == resultCode; + } + + /** Pretty print */ + @Override + public String toString() { + switch (resultCode) { + case SUCCESS: return "SUCCESS"; + case ERROR_GENERIC: return "GENERIC ERROR"; + case ERROR_ILLEGAL_ARGUMENT: return "ILLEGAL ARGUMENT"; + case ERROR_DATABASE_CANNOT_BE_OPENED: return "DATABASE CANNOT BE OPENED"; + // "DB storage error" is not very helpful but SQLite does not provide specific error + // codes upon store failure. Thus this indicates SQLite returned some error upon store + case ERROR_STORAGE: return "DATABASE STORAGE ERROR"; + default: return "Unknown value ?!"; + } + } +} diff --git a/common/networkstackclient/src/android/net/ipmemorystore/StatusParcelable.aidl b/common/networkstackclient/src/android/net/ipmemorystore/StatusParcelable.aidl new file mode 100644 index 0000000..fb36ef4 --- /dev/null +++ b/common/networkstackclient/src/android/net/ipmemorystore/StatusParcelable.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2018 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; + +/** {@hide} */ +parcelable StatusParcelable { + int resultCode; +} |