System operacyjny Android Auto w wersji 13 lub nowszej zawiera funkcje umożliwiające konfigurowanie sieci Ethernet i zarządzanie nimi. Rysunek 1 przedstawia przykładowy diagram sieci samochodu:
Rysunek 1. Sieciowanie w Androidzie Auto.
Rysunek przedstawia metody wywoływania aplikacji sieciowej OEM w klasie EthernetManager
, które służą do konfigurowania sieci Ethernet (eth0.1, eth0.2 i eth0.3) i zarządzania nimi. Pozostała część rysunku 1 wykracza poza zakres tego dokumentu.
Ustawianie domyślnych ustawień sieci Ethernet
Aby ustawić domyślne ustawienia sieci, użyj nakładki zasobów: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>
Ten przykład pokazuje nakładkę zasobu config_ethernet_interfaces
z config.xml
.
Najważniejsze informacje o kodzie
eth1
,eth2
ieth3
to nazwy konfigurowanych interfejsów sieciowych.- Kolejne numery
12, 13, 14, 15
oznaczają włączone możliwości sieci. ip=
,gateway=
idns
służą do konfigurowania początkowego adresu IP, bramy i serwera DNS sieci.
Włączanie i wyłączanie interfejsu sieciowego
Aby włączyć interfejs sieci, uruchom:
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);
}
}
Najważniejsze informacje o kodzie
ifaceName
to nazwa interfejsu sieciowego, który ma zostać włączony.getMainExecutor()
zwraca kontekst aplikacji.OutcomeReceiver
to funkcja wywoływana z powrotem, która przekazuje informacje o wypełnieniu, zwracając zaktualizowaną nazwę sieci w przypadku powodzenia lubEthernetNetworkManagementException
w przypadku błędu.
Gdy interfejs sieciowy jest włączony, korzysta z konfiguracji ustawionej przez EthernetManager.updateConfiguration()
. Jeśli konfiguracja nie została ustawiona za pomocą EthernetManager.updateConfiguration()
, interfejs sieciowy używa nakładki zasobów config_ethernet_interfaces
lub domyślnej konfiguracji sieci Ethernet, jeśli nakładka jest niedostępna.
Aby wyłączyć interfejs sieci, wywołaj:
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);
}
}
Najważniejsze informacje o kodzie
ifaceName
to nazwa interfejsu sieciowego, który chcesz wyłączyć.getMainExecutor()
zwraca kontekst aplikacji.OutcomeReceiver
to funkcja wywoływana z powrotem, która przekazuje informacje o wypełnieniu, zwracając zaktualizowaną nazwę sieci w przypadku powodzenia lubEthernetNetworkManagementException
w przypadku błędu.
Aktualizacja konfiguracji sieci
Aby zaktualizować konfiguracje sieci Ethernet, wywołaj: 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);
}
}
Najważniejsze informacje o kodzie
getCapabilities()
to metoda pomocnicza, która pobiera bieżące możliwości sieci i wywołuje funkcjęconvertToUIDs()
, aby przekonwertować czytelne dla człowieka nazwy pakietów na unikalny identyfikator (UID) w Linuksie. Zwykle nie znasz z góry identyfikatorów UID powiązanych pakietów. Jeśli więc chcesz użyć funkcjiEthernetManager.updateConfiguration()
, aby ograniczyć dostęp do podzbioru aplikacji, musisz użyć ich identyfikatorów UID.request
to konfiguracja używana w przypadku sieci wewnętrznej. Prośba może zawierać nowe ustawienia konfiguracji adresu IP i możliwości sieci. Jeśli sieć jest zarejestrowana w stosie łączności, jest aktualizowana zgodnie z konfiguracją. Ta konfiguracja nie jest zachowywana po ponownym uruchomieniu.getMainExecutor()
zwraca wykonawcę, w którym wywoływany jest listener.mCallback
to wywołanie zwrotne służące do przekazywania informacji o zakończeniu. W razie powodzenia zwraca ono zaktualizowaną nazwę sieci, a w razie błędu –EthernetNetworkManagementException
.
updateConfiguration()
może zaktualizować właściwości sieci, które są uważane za niezmienne przez pakiet Android Connectivity. Sieć jest wyłączana, aktualizowana i ponownie włączana, aby można było zaktualizować te niezmienne atrybuty.
Ograniczanie sieci do podzbioru aplikacji
Możesz użyć atrybutu EthernetManager#updateConfiguration
, aby ograniczyć dostęp tylko do podzbioru dozwolonych identyfikatorów UID. Używaj tej metody w przypadkach, gdy jest to wymagane, np. w przypadku wewnętrznych sieci pojazdowych, które mogą korzystać tylko z małej podgrupy aplikacji OEM.
Android śledzi aplikacje głównie na podstawie ich identyfikatorów UID.
Poniższy kod z UIDToPackageNameConverter.java
pokazuje, jak uzyskać serię identyfikatorów UID z ciągu nazw pakietów:
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;
Najważniejsze informacje o kodzie
getApplicationInfoAsuser().uid
służy do pobierania identyfikatora UID z nazwy pakietu.uids
to wygenerowana tablica liczb całkowitych.
Ten kod w EthernetManagerTest.kt
pokazuje, jak zaktualizować konfigurację interfejsu sieciowego za pomocą identyfikatorów UID aplikacji, które mogą korzystać z sieci:
val allowedUids = setOf(Process.myUid())
val nc = NetworkCapabilities.Builder(request.networkCapabilities)
.setAllowedUids(allowedUids).build()
updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
Najważniejsze informacje o kodzie
allowUids
to zbiór identyfikatorów UID aplikacji, które mogą korzystać z sieci.updateConfiguration()
aktualizuje konfigurację, aby ograniczyć sieć do podanego zbioru identyfikatorów UID.