Merge "Add proto to store network configuration" into main

This commit is contained in:
Treehugger Robot 2025-07-25 16:48:31 -07:00 • committed by Android (Google) Code Review
commit 3e3e18b2f1
3 changed files with 240 additions and 0 deletions

View file

@ -72,6 +72,7 @@ java_library {
// service-connectivity-pre-jarjar), and in the case of code that is already in
// framework-connectivity, the classes would be included in the apex twice.
"modules-utils-statemachine",
"service-connectivity-tiramisu-protos",
],
apex_available: [
"com.android.tethering",
@ -92,6 +93,24 @@ java_library {
},
}
java_library {
name: "service-connectivity-tiramisu-protos",
sdk_version: "core_current",
proto: {
type: "lite",
},
srcs: [
"src/proto/*.proto",
],
static_libs: ["libprotobuf-java-lite"],
apex_available: [
"com.android.tethering",
],
lint: {
strict_updatability_linting: true,
},
}
// Test building mDNS as a standalone, so that it can be imported into other repositories as-is.
// The mDNS code is platform code so it should use framework-annotations-lib, contrary to apps that
// should use sdk_version: "system_current" and only androidx.annotation_annotation. But this build

View file

@ -0,0 +1,117 @@
/*
* Copyright (C) 2025 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.
*/
// This file contains messages for representing the basic information and
// configuration of an network interface.
//
// Messages defined in this file are stored on disk, so reader should be able
// to parse all historic versions of the serialized data, and to merge data
// with different serialization formats.
syntax = "proto2";
package com_android_server_network_configstore;
option java_package = "com.android.server.network.configstore.proto";
option java_outer_classname = "NetworkConfigStoreProto";
// Represents an IPv4 address along with its prefix length.
message LinkAddress {
// The string of the IPv4 address in the format of IPv4 address in dotted decimal notation, for
// example "192.168.1.50".
required string address = 1;
// The prefix length of the IP address, indicating the subnet mask.
required int32 prefix_length = 2;
}
// Configuration for a static IPv4 assignment.
message StaticIpv4Configuration {
// The IPv4 address and prefix length for the static IPv4 configuration.
required LinkAddress address = 1;
// The gateway IPv4 address as string in the format of IPv4 address in dotted decimal notation,
// for example "192.168.1.100".
optional string gateway = 2;
// A list of DNS server IPv4 addresses as strings in the format of IPv4 address in dotted
// decimal notation, for example "8.8.8.8".
repeated string dns_servers = 3;
// A list of domains to search when resolving host names on this link, in priority order.
repeated string search_domains = 4;
}
// Manual configuration of the proxy server.
message ManualProxyConfig {
// A list of hosts for which the proxy should not be used.
repeated string exclusion_hosts = 1;
// The hostname or IP address of the proxy server.
required string host = 2;
// The port number of the proxy server.
required int32 port = 3;
}
// Configuration using a PAC (Proxy Auto-Configuration) script downloaded from a URL.
message PacUrlConfig {
// The URL of the Proxy Auto-Configuration (PAC) file.
required string pac_url = 1;
}
// IP configuration for the interface.
message IpConfiguration {
// IPv4 configuration of this interface. Making this an oneoff field because of the possibility
// of adding DHCP IPv4 configuration in the future.
oneof ipv4_configuration {
// Static IPv4 configuration of this interface. DHCP is not used when a static configuration
// exists.
StaticIpv4Configuration static_ipv4_config = 1;
}
// Proxy configuration to use for network connections on this interface, when not set, means
// no proxy configuration is used.
oneof proxy_config {
// Manual proxy configuration.
ManualProxyConfig manual_proxy_config = 2;
// PAC (Proxy Auto-Configuration) configuration.
PacUrlConfig pac_url_config = 3;
}
}
// Defines a selector to identify the ethernet port.
message EthernetPortSelector {
oneof identifier {
// MAC address of this ethernet port.
string mac_addr = 1;
// Interface name of this ethernet port.
string iface_name = 2;
}
}
// Enum for metered override configuration.
enum MeteredOverride {
// There is no metered override configuration.
METERED_OVERRIDE_NONE = 0;
// Forces the connection to be treated as metered.
METERED_OVERRIDE_FORCE_METERED = 1;
// Forces the connection to be treated as unmetered.
METERED_OVERRIDE_FORCE_UNMETERED = 2;
}
// Defines the configuration of an ethernet interface.
message EthernetConfiguration {
// Selector for applying this configuration to an Ethernet port, containing identifiable
// information of related ethernet port.
required EthernetPortSelector selector = 1;
// IP configuration of this ethernet interface.
required IpConfiguration ip_config = 2;
// Static metered override configuration, note that this is not the actual meteredness but
// static configuration.
required MeteredOverride metered_override = 3;
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (C) 2025 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 androidx.test.filters.SmallTest
import com.android.server.network.configstore.proto.NetworkConfigStoreProto
import com.android.server.network.configstore.proto.NetworkConfigStoreProto.MeteredOverride
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.MockitoAnnotations
/**
* Unit tests for [com.android.server.ethernet.proto.NetworkConfigStoreProto].
*/
@SmallTest
class NetworkConfigStoreProtoTest {
companion object {
private const val IFACE_NAME = "eth0"
private const val ADDR = "192.0.2.1"
private const val PREFIX_LEN = 25
private const val GATEWAY = "192.0.2.129"
private const val DNS1 = "8.8.8.8"
private const val DNS2 = "8.8.8.4"
private const val EXCLUSION_LIST1 = "com.example.app"
private const val EXCLUSION_LIST2 = "localhost"
private const val PROXY_HOST = "proxy.example.com"
private const val PROXY_PORT = 8080
}
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun testBuilder() {
val selector = NetworkConfigStoreProto.EthernetPortSelector.newBuilder().apply {
ifaceName = IFACE_NAME
}.build()
assertEquals(IFACE_NAME, selector.ifaceName)
val linkAddr = NetworkConfigStoreProto.LinkAddress.newBuilder().apply {
address = ADDR
prefixLength = PREFIX_LEN
}.build()
assertEquals(ADDR, linkAddr.address)
assertEquals(PREFIX_LEN, linkAddr.prefixLength)
val staticIpv4Configuration =
NetworkConfigStoreProto.StaticIpv4Configuration.newBuilder().apply {
address = linkAddr
gateway = GATEWAY
addDnsServers(DNS1)
addDnsServers(DNS2)
}.build()
assertEquals(linkAddr, staticIpv4Configuration.address)
assertEquals(GATEWAY, staticIpv4Configuration.gateway)
assertEquals(DNS1, staticIpv4Configuration.getDnsServers(0))
assertEquals(DNS2, staticIpv4Configuration.getDnsServers(1))
val manualProxy = NetworkConfigStoreProto.ManualProxyConfig.newBuilder().apply {
host = PROXY_HOST
port = PROXY_PORT
addExclusionHosts(EXCLUSION_LIST1)
addExclusionHosts(EXCLUSION_LIST2)
}.build()
assertEquals(PROXY_HOST, manualProxy.host)
assertEquals(PROXY_PORT, manualProxy.port)
assertEquals(EXCLUSION_LIST1, manualProxy.getExclusionHosts(0))
assertEquals(EXCLUSION_LIST2, manualProxy.getExclusionHosts(1))
val ipConfig = NetworkConfigStoreProto.IpConfiguration.newBuilder().apply {
staticIpv4Config = staticIpv4Configuration
manualProxyConfig = manualProxy
}.build()
assertEquals(staticIpv4Configuration, ipConfig.staticIpv4Config)
assertEquals(manualProxy, ipConfig.manualProxyConfig)
val ethConfig = NetworkConfigStoreProto.EthernetConfiguration.newBuilder().apply {
setSelector(selector)
setIpConfig(ipConfig)
meteredOverride = MeteredOverride.METERED_OVERRIDE_FORCE_METERED
}.build()
assertEquals(selector, ethConfig.selector)
assertEquals(ipConfig, ethConfig.ipConfig)
assertEquals(MeteredOverride.METERED_OVERRIDE_FORCE_METERED, ethConfig.meteredOverride)
assertEquals(staticIpv4Configuration, ethConfig.ipConfig.staticIpv4Config)
}
}