В Android Auto OS 13 и более поздних версиях содержатся функции, позволяющие настраивать и управлять сетями Ethernet. На рисунке 1 показана примерная схема сети для автомобиля:

Рисунок 1. Работа сети в Android Auto.
На этом рисунке показано, как ваше OEM-приложение для работы с сетью вызывает методы класса EthernetManager для настройки и управления встроенными сетями Ethernet (eth0.1, eth0.2 и eth0.3). Остальная часть рисунка 1 выходит за рамки данного документа.
Установить параметры сети Ethernet по умолчанию
Для установки параметров сети по умолчанию используйте наложение ресурсов config_ethernet_interfaces :
<string-array translatable="false" name="config_ethernet_interfaces">
<!--
<item>eth1;12,13,14,15;ip=192.168.0.10/24 gateway=192.168.0.1 dns=4.4.4.4,8.8.8.8</item>
<item>eth2;;ip=192.168.0.11/24</item>
<item>eth3;12,13,14,15;ip=192.168.0.12/24;1</item>
-->
</string-array>
В этом примере показано наложение ресурса config_ethernet_interfaces из config.xml .
Основные моменты, касающиеся кода.
-
eth1,eth2иeth3— это имена настраиваемых сетевых интерфейсов. - Последовательные числа
12, 13, 14, 15обозначают включение сетевых возможностей . -
ip=,gateway=иdnsиспользуются для установки начального IP-адреса, шлюза и DNS для сети.
Включение или отключение сетевого интерфейса
Для включения сетевого интерфейса вызовите метод EthernetManager.enableInterface() :
public final class InterfaceEnabler {
private final Context mApplicationContext;
private final EthernetManager mEthernetManager;
private final OutcomeReceiver<String, EthernetNetworkManagementException> mOutcomeReceiver;
public InterfaceEnabler(Context applicationContext,
OutcomeReceiver<String, EthernetNetworkManagementException> outcomeReceiver) {
mApplicationContext = applicationContext;
mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
mOutcomeReceiver = outcomeReceiver;
}
public void enableInterface(String ifaceName) {
mEthernetManager.enableInterface(ifaceName,
mApplicationContext.getMainExecutor(),
mOutcomeReceiver);
}
}
Основные моменты, касающиеся кода.
-
ifaceName— это имя сетевого интерфейса, который необходимо включить. -
getMainExecutor()возвращает контекст приложения. -
OutcomeReceiver— это функция обратного вызова, используемая для сообщения о завершении процесса, возвращающая обновленное имя сети в случае успеха илиEthernetNetworkManagementExceptionв случае ошибки.
Когда сетевой интерфейс включен, он использует конфигурацию, заданную функцией EthernetManager.updateConfiguration() . Если конфигурация не была задана функцией EthernetManager.updateConfiguration() , сетевой интерфейс использует ресурсную оверлейную конфигурацию config_ethernet_interfaces или конфигурацию сети Ethernet по умолчанию, если оверлейная конфигурация недоступна.
Чтобы отключить сетевой интерфейс, вызовите метод EthernetManager.disableInterface() :
public final class InterfaceEnabler {
private final Context mApplicationContext;
private final EthernetManager mEthernetManager;
private final OutcomeReceiver<String, EthernetNetworkManagementException> mOutcomeReceiver;
public InterfaceEnabler(Context applicationContext,
OutcomeReceiver<String, EthernetNetworkManagementException> outcomeReceiver) {
mApplicationContext = applicationContext;
mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
mOutcomeReceiver = outcomeReceiver;
}
public void disableInterface(String ifaceName) {
mEthernetManager.disableInterface(ifaceName,
mApplicationContext.getMainExecutor(),
mOutcomeReceiver);
}
}
Основные моменты, касающиеся кода.
-
ifaceName— это имя сетевого интерфейса, который нужно отключить. -
getMainExecutor()возвращает контекст приложения. -
OutcomeReceiver— это функция обратного вызова, используемая для сообщения о завершении процесса, возвращающая обновленное имя сети в случае успеха илиEthernetNetworkManagementExceptionв случае ошибки.
Обновить сетевую конфигурацию
Для обновления конфигурации сети Ethernet вызовите метод EthernetManager.updateConfiguration() :
public final class ConfigurationUpdater {
private final Context mApplicationContext;
private final EthernetManager mEthernetManager;
private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;
public ConfigurationUpdater(Context applicationContext,
OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
mApplicationContext = applicationContext;
mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
mCallback = callback;
}
public void updateNetworkConfiguration(String packageNames,
String ipConfigurationText,
String networkCapabilitiesText,
String interfaceName)
throws IllegalArgumentException, PackageManager.NameNotFoundException {
EthernetNetworkUpdateRequest request = new EthernetNetworkUpdateRequest.Builder()
.setIpConfiguration(getIpConfiguration(ipConfigurationText))
.setNetworkCapabilities(getCapabilities(
interfaceName, networkCapabilitiesText, packageNames))
.build();
mEthernetManager.updateConfiguration(interfaceName, request,
mApplicationContext.getMainExecutor(), mCallback);
}
}
Основные моменты, касающиеся кода.
-
getCapabilities()— это вспомогательный метод, который получает текущие сетевые возможности и вызываетconvertToUIDs()для преобразования удобочитаемых имен пакетов в уникальные идентификаторы Linux (UID) . Как правило, UID для связанных с ними пакетов заранее неизвестны. Поэтому, если вы хотите использоватьEthernetManager.updateConfiguration()для ограничения доступа к подмножеству приложений, вам необходимо использовать их UID. -
requestпредставляет собой конфигурацию, используемую для внутренней сети. Запрос может содержать новые настройки IP-адреса и сетевых возможностей. Если сеть зарегистрирована в стеке подключения, она обновляется в соответствии с конфигурацией. Эта конфигурация не сохраняется после перезагрузки. -
getMainExecutor()возвращает исполнитель, на котором вызывается обработчик событий. -
mCallback— это функция обратного вызова, используемая для сообщения о завершении процесса, возвращающая обновленное имя сети в случае успеха илиEthernetNetworkManagementExceptionв случае ошибки.
updateConfiguration() может обновлять характеристики сети, которые считаются неизменяемыми стеком подключения Android. Для обновления этих неизменяемых атрибутов сеть отключается, обновляется и снова включается.
Ограничить доступ к сети определенным набором приложений.
Вы можете использовать EthernetManager#updateConfiguration , чтобы ограничить доступ только к подмножеству разрешенных UID. Используйте этот метод для случаев, когда это необходимо, например, для внутренних автомобильных сетей, доступных только для небольшого подмножества приложений OEM.
В Android приложения отслеживаются в основном по их UID. Следующий код из файла UIDToPackageNameConverter.java показывает, как получить последовательность UID из строки имен пакетов:
public static Set<Integer> convertToUids(Context applicationContext, String packageNames)
throws PackageManager.NameNotFoundException {
final PackageManager packageManager = applicationContext.getPackageManager();
final UserManager userManager = applicationContext.getSystemService(UserManager.class);
final Set<Integer> uids = new ArraySet<>();
final List<UserHandle> users = userManager.getUserHandles(true);
String[] packageNamesArray = packageNames.split(",");
for (String packageName : packageNamesArray) {
boolean nameNotFound = true;
packageName = packageName.trim();
for (final UserHandle user : users) {
try {
final int uid =
packageManager.getApplicationInfoAsUser(packageName, 0, user).uid;
uids.add(uid);
nameNotFound = false;
} catch (PackageManager.NameNotFoundException e) {
// Although this may seem like an error scenario, it is OK as all packages are
// not expected to be installed for all users.
continue;
}
}
if (nameNotFound) {
throw new PackageManager.NameNotFoundException("Not installed: " + packageName);
}
}
return uids;
Основные моменты, касающиеся кода.
-
getApplicationInfoAsuser().uidиспользуется для получения UID из имени пакета. -
uids— это сгенерированный массив целых чисел.
Следующий код в файле EthernetManagerTest.kt показывает, как обновить конфигурацию сетевого интерфейса, указав UID приложений, которым разрешено использовать сеть:
val allowedUids = setOf(Process.myUid())
val nc = NetworkCapabilities.Builder(request.networkCapabilities)
.setAllowedUids(allowedUids).build()
updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
Основные моменты, касающиеся кода.
-
allowUids— это набор идентификаторов приложений (UID), которым разрешено использовать сеть. -
updateConfiguration()обновляет конфигурацию, ограничивая сеть указанным набором UID.