Move Ethernet related files to f/b/packages/ConnectivityT.
ethernet-service is going to be moved into Connectivity mainline module.
Move all ethernet related files in f/b/ to f/b/packages/ConnectivityT so
that it's easier to migrate these files to Connectivity module finally
after clearing the hidden API usages. Below files to be moved:
Ethernet framework related files:
- EthernetManager.java
- EthernetNetworkSpecifier.java
- IEthernetManager.aidl
- IEthernetServiceListener.aidl
- ITetheredInterfaceCallback.aidl
Ethernet service related files:
- IpConfigStore.java(EthernetConfigStore has dependency on the class)
For the ethernet-service related files, keep it as-is temproraliy and
fix the hiden API dependencies in f/opt/net/ethernet/. After this work
is done, then migrating the whole of ethernet folder to Connectivity
module completely.
This CL also fixes some minor errors of code style format to pass the
code style check.
Bug: 210586283
Test: build pass
atest FrameworksNetTests
atest EthernetServiceTests
Change-Id: Ib359d29d5221105f648bc4194c6d6dbe4cc6e3e5
diff --git a/service-t/Sources.bp b/service-t/Sources.bp
index 7b88176..97dfb64 100644
--- a/service-t/Sources.bp
+++ b/service-t/Sources.bp
@@ -61,11 +61,25 @@
],
}
+// Ethernet related libraries.
+
+filegroup {
+ name: "services.connectivity-ethernet-sources",
+ srcs: [
+ "src/com/android/server/net/IpConfigStore.java",
+ ],
+ path: "src",
+ visibility: [
+ "//frameworks/opt/net/ethernet",
+ ],
+}
+
// Connectivity-T common libraries.
filegroup {
name: "services.connectivity-tiramisu-sources",
srcs: [
+ ":services.connectivity-ethernet-sources",
":services.connectivity-ipsec-sources",
":services.connectivity-netstats-sources",
":services.connectivity-nsd-sources",
diff --git a/service-t/src/com/android/server/net/IpConfigStore.java b/service-t/src/com/android/server/net/IpConfigStore.java
new file mode 100644
index 0000000..3a9a544
--- /dev/null
+++ b/service-t/src/com/android/server/net/IpConfigStore.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2014 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.net;
+
+import android.net.InetAddresses;
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.ProxyInfo;
+import android.net.StaticIpConfiguration;
+import android.net.Uri;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.ProxyUtils;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.EOFException;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides an API to store and manage L3 network IP configuration.
+ */
+public class IpConfigStore {
+ private static final String TAG = "IpConfigStore";
+ private static final boolean DBG = false;
+
+ protected final DelayedDiskWrite mWriter;
+
+ /* IP and proxy configuration keys */
+ protected static final String ID_KEY = "id";
+ protected static final String IP_ASSIGNMENT_KEY = "ipAssignment";
+ protected static final String LINK_ADDRESS_KEY = "linkAddress";
+ protected static final String GATEWAY_KEY = "gateway";
+ protected static final String DNS_KEY = "dns";
+ protected static final String PROXY_SETTINGS_KEY = "proxySettings";
+ protected static final String PROXY_HOST_KEY = "proxyHost";
+ protected static final String PROXY_PORT_KEY = "proxyPort";
+ protected static final String PROXY_PAC_FILE = "proxyPac";
+ protected static final String EXCLUSION_LIST_KEY = "exclusionList";
+ protected static final String EOS = "eos";
+
+ protected static final int IPCONFIG_FILE_VERSION = 3;
+
+ public IpConfigStore(DelayedDiskWrite writer) {
+ mWriter = writer;
+ }
+
+ public IpConfigStore() {
+ this(new DelayedDiskWrite());
+ }
+
+ private static boolean writeConfig(DataOutputStream out, String configKey,
+ IpConfiguration config) throws IOException {
+ return writeConfig(out, configKey, config, IPCONFIG_FILE_VERSION);
+ }
+
+ /**
+ * Write the IP configuration with the given parameters to {@link DataOutputStream}.
+ */
+ @VisibleForTesting
+ public static boolean writeConfig(DataOutputStream out, String configKey,
+ IpConfiguration config, int version) throws IOException {
+ boolean written = false;
+
+ try {
+ switch (config.getIpAssignment()) {
+ case STATIC:
+ out.writeUTF(IP_ASSIGNMENT_KEY);
+ out.writeUTF(config.getIpAssignment().toString());
+ StaticIpConfiguration staticIpConfiguration = config.getStaticIpConfiguration();
+ if (staticIpConfiguration != null) {
+ if (staticIpConfiguration.getIpAddress() != null) {
+ LinkAddress ipAddress = staticIpConfiguration.getIpAddress();
+ out.writeUTF(LINK_ADDRESS_KEY);
+ out.writeUTF(ipAddress.getAddress().getHostAddress());
+ out.writeInt(ipAddress.getPrefixLength());
+ }
+ if (staticIpConfiguration.getGateway() != null) {
+ out.writeUTF(GATEWAY_KEY);
+ out.writeInt(0); // Default route.
+ out.writeInt(1); // Have a gateway.
+ out.writeUTF(staticIpConfiguration.getGateway().getHostAddress());
+ }
+ for (InetAddress inetAddr : staticIpConfiguration.getDnsServers()) {
+ out.writeUTF(DNS_KEY);
+ out.writeUTF(inetAddr.getHostAddress());
+ }
+ }
+ written = true;
+ break;
+ case DHCP:
+ out.writeUTF(IP_ASSIGNMENT_KEY);
+ out.writeUTF(config.getIpAssignment().toString());
+ written = true;
+ break;
+ case UNASSIGNED:
+ /* Ignore */
+ break;
+ default:
+ loge("Ignore invalid ip assignment while writing");
+ break;
+ }
+
+ switch (config.getProxySettings()) {
+ case STATIC:
+ ProxyInfo proxyProperties = config.getHttpProxy();
+ String exclusionList = ProxyUtils.exclusionListAsString(
+ proxyProperties.getExclusionList());
+ out.writeUTF(PROXY_SETTINGS_KEY);
+ out.writeUTF(config.getProxySettings().toString());
+ out.writeUTF(PROXY_HOST_KEY);
+ out.writeUTF(proxyProperties.getHost());
+ out.writeUTF(PROXY_PORT_KEY);
+ out.writeInt(proxyProperties.getPort());
+ if (exclusionList != null) {
+ out.writeUTF(EXCLUSION_LIST_KEY);
+ out.writeUTF(exclusionList);
+ }
+ written = true;
+ break;
+ case PAC:
+ ProxyInfo proxyPacProperties = config.getHttpProxy();
+ out.writeUTF(PROXY_SETTINGS_KEY);
+ out.writeUTF(config.getProxySettings().toString());
+ out.writeUTF(PROXY_PAC_FILE);
+ out.writeUTF(proxyPacProperties.getPacFileUrl().toString());
+ written = true;
+ break;
+ case NONE:
+ out.writeUTF(PROXY_SETTINGS_KEY);
+ out.writeUTF(config.getProxySettings().toString());
+ written = true;
+ break;
+ case UNASSIGNED:
+ /* Ignore */
+ break;
+ default:
+ loge("Ignore invalid proxy settings while writing");
+ break;
+ }
+
+ if (written) {
+ out.writeUTF(ID_KEY);
+ if (version < 3) {
+ out.writeInt(Integer.valueOf(configKey));
+ } else {
+ out.writeUTF(configKey);
+ }
+ }
+ } catch (NullPointerException e) {
+ loge("Failure in writing " + config + e);
+ }
+ out.writeUTF(EOS);
+
+ return written;
+ }
+
+ /**
+ * @deprecated use {@link #writeIpConfigurations(String, ArrayMap)} instead.
+ * New method uses string as network identifier which could be interface name or MAC address or
+ * other token.
+ */
+ @Deprecated
+ public void writeIpAndProxyConfigurationsToFile(String filePath,
+ final SparseArray<IpConfiguration> networks) {
+ mWriter.write(filePath, out -> {
+ out.writeInt(IPCONFIG_FILE_VERSION);
+ for (int i = 0; i < networks.size(); i++) {
+ writeConfig(out, String.valueOf(networks.keyAt(i)), networks.valueAt(i));
+ }
+ });
+ }
+
+ /**
+ * Write the IP configuration associated to the target networks to the destination path.
+ */
+ public void writeIpConfigurations(String filePath,
+ ArrayMap<String, IpConfiguration> networks) {
+ mWriter.write(filePath, out -> {
+ out.writeInt(IPCONFIG_FILE_VERSION);
+ for (int i = 0; i < networks.size(); i++) {
+ writeConfig(out, networks.keyAt(i), networks.valueAt(i));
+ }
+ });
+ }
+
+ /**
+ * Read the IP configuration from the destination path to {@link BufferedInputStream}.
+ */
+ public static ArrayMap<String, IpConfiguration> readIpConfigurations(String filePath) {
+ BufferedInputStream bufferedInputStream;
+ try {
+ bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
+ } catch (FileNotFoundException e) {
+ // Return an empty array here because callers expect an empty array when the file is
+ // not present.
+ loge("Error opening configuration file: " + e);
+ return new ArrayMap<>(0);
+ }
+ return readIpConfigurations(bufferedInputStream);
+ }
+
+ /** @deprecated use {@link #readIpConfigurations(String)} */
+ @Deprecated
+ public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(String filePath) {
+ BufferedInputStream bufferedInputStream;
+ try {
+ bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
+ } catch (FileNotFoundException e) {
+ // Return an empty array here because callers expect an empty array when the file is
+ // not present.
+ loge("Error opening configuration file: " + e);
+ return new SparseArray<>();
+ }
+ return readIpAndProxyConfigurations(bufferedInputStream);
+ }
+
+ /** @deprecated use {@link #readIpConfigurations(InputStream)} */
+ @Deprecated
+ public static SparseArray<IpConfiguration> readIpAndProxyConfigurations(
+ InputStream inputStream) {
+ ArrayMap<String, IpConfiguration> networks = readIpConfigurations(inputStream);
+ if (networks == null) {
+ return null;
+ }
+
+ SparseArray<IpConfiguration> networksById = new SparseArray<>();
+ for (int i = 0; i < networks.size(); i++) {
+ int id = Integer.valueOf(networks.keyAt(i));
+ networksById.put(id, networks.valueAt(i));
+ }
+
+ return networksById;
+ }
+
+ /** Returns a map of network identity token and {@link IpConfiguration}. */
+ public static ArrayMap<String, IpConfiguration> readIpConfigurations(
+ InputStream inputStream) {
+ ArrayMap<String, IpConfiguration> networks = new ArrayMap<>();
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(inputStream);
+
+ int version = in.readInt();
+ if (version != 3 && version != 2 && version != 1) {
+ loge("Bad version on IP configuration file, ignore read");
+ return null;
+ }
+
+ while (true) {
+ String uniqueToken = null;
+ // Default is DHCP with no proxy
+ IpAssignment ipAssignment = IpAssignment.DHCP;
+ ProxySettings proxySettings = ProxySettings.NONE;
+ StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+ LinkAddress linkAddress = null;
+ InetAddress gatewayAddress = null;
+ String proxyHost = null;
+ String pacFileUrl = null;
+ int proxyPort = -1;
+ String exclusionList = null;
+ String key;
+ final List<InetAddress> dnsServers = new ArrayList<>();
+
+ do {
+ key = in.readUTF();
+ try {
+ if (key.equals(ID_KEY)) {
+ if (version < 3) {
+ int id = in.readInt();
+ uniqueToken = String.valueOf(id);
+ } else {
+ uniqueToken = in.readUTF();
+ }
+ } else if (key.equals(IP_ASSIGNMENT_KEY)) {
+ ipAssignment = IpAssignment.valueOf(in.readUTF());
+ } else if (key.equals(LINK_ADDRESS_KEY)) {
+ LinkAddress parsedLinkAddress =
+ new LinkAddress(
+ InetAddresses.parseNumericAddress(in.readUTF()),
+ in.readInt());
+ if (parsedLinkAddress.getAddress() instanceof Inet4Address
+ && linkAddress == null) {
+ linkAddress = parsedLinkAddress;
+ } else {
+ loge("Non-IPv4 or duplicate address: " + parsedLinkAddress);
+ }
+ } else if (key.equals(GATEWAY_KEY)) {
+ LinkAddress dest = null;
+ InetAddress gateway = null;
+ if (version == 1) {
+ // only supported default gateways - leave the dest/prefix empty
+ gateway = InetAddresses.parseNumericAddress(in.readUTF());
+ if (gatewayAddress == null) {
+ gatewayAddress = gateway;
+ } else {
+ loge("Duplicate gateway: " + gateway.getHostAddress());
+ }
+ } else {
+ if (in.readInt() == 1) {
+ dest =
+ new LinkAddress(
+ InetAddresses.parseNumericAddress(in.readUTF()),
+ in.readInt());
+ }
+ if (in.readInt() == 1) {
+ gateway = InetAddresses.parseNumericAddress(in.readUTF());
+ }
+ // If the destination is a default IPv4 route, use the gateway
+ // address unless already set. If there is no destination, assume
+ // it is default route and use the gateway address in all cases.
+ if (dest == null) {
+ gatewayAddress = gateway;
+ } else if (dest.getAddress() instanceof Inet4Address
+ && dest.getPrefixLength() == 0 && gatewayAddress == null) {
+ gatewayAddress = gateway;
+ } else {
+ loge("Non-IPv4 default or duplicate route: "
+ + dest.getAddress());
+ }
+ }
+ } else if (key.equals(DNS_KEY)) {
+ dnsServers.add(InetAddresses.parseNumericAddress(in.readUTF()));
+ } else if (key.equals(PROXY_SETTINGS_KEY)) {
+ proxySettings = ProxySettings.valueOf(in.readUTF());
+ } else if (key.equals(PROXY_HOST_KEY)) {
+ proxyHost = in.readUTF();
+ } else if (key.equals(PROXY_PORT_KEY)) {
+ proxyPort = in.readInt();
+ } else if (key.equals(PROXY_PAC_FILE)) {
+ pacFileUrl = in.readUTF();
+ } else if (key.equals(EXCLUSION_LIST_KEY)) {
+ exclusionList = in.readUTF();
+ } else if (key.equals(EOS)) {
+ break;
+ } else {
+ loge("Ignore unknown key " + key + "while reading");
+ }
+ } catch (IllegalArgumentException e) {
+ loge("Ignore invalid address while reading" + e);
+ }
+ } while (true);
+
+ staticIpConfiguration = new StaticIpConfiguration.Builder()
+ .setIpAddress(linkAddress)
+ .setGateway(gatewayAddress)
+ .setDnsServers(dnsServers)
+ .build();
+
+ if (uniqueToken != null) {
+ IpConfiguration config = new IpConfiguration();
+ networks.put(uniqueToken, config);
+
+ switch (ipAssignment) {
+ case STATIC:
+ config.setStaticIpConfiguration(staticIpConfiguration);
+ config.setIpAssignment(ipAssignment);
+ break;
+ case DHCP:
+ config.setIpAssignment(ipAssignment);
+ break;
+ case UNASSIGNED:
+ loge("BUG: Found UNASSIGNED IP on file, use DHCP");
+ config.setIpAssignment(IpAssignment.DHCP);
+ break;
+ default:
+ loge("Ignore invalid ip assignment while reading.");
+ config.setIpAssignment(IpAssignment.UNASSIGNED);
+ break;
+ }
+
+ switch (proxySettings) {
+ case STATIC:
+ ProxyInfo proxyInfo = ProxyInfo.buildDirectProxy(proxyHost, proxyPort,
+ ProxyUtils.exclusionStringAsList(exclusionList));
+ config.setProxySettings(proxySettings);
+ config.setHttpProxy(proxyInfo);
+ break;
+ case PAC:
+ ProxyInfo proxyPacProperties =
+ ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl));
+ config.setProxySettings(proxySettings);
+ config.setHttpProxy(proxyPacProperties);
+ break;
+ case NONE:
+ config.setProxySettings(proxySettings);
+ break;
+ case UNASSIGNED:
+ loge("BUG: Found UNASSIGNED proxy on file, use NONE");
+ config.setProxySettings(ProxySettings.NONE);
+ break;
+ default:
+ loge("Ignore invalid proxy settings while reading");
+ config.setProxySettings(ProxySettings.UNASSIGNED);
+ break;
+ }
+ } else {
+ if (DBG) log("Missing id while parsing configuration");
+ }
+ }
+ } catch (EOFException ignore) {
+ } catch (IOException e) {
+ loge("Error parsing configuration: " + e);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (Exception e) { }
+ }
+ }
+
+ return networks;
+ }
+
+ protected static void loge(String s) {
+ Log.e(TAG, s);
+ }
+
+ protected static void log(String s) {
+ Log.d(TAG, s);
+ }
+}