Android Auto OS 13 und höher enthält Funktionen, mit denen Sie Ethernet-Netzwerke konfigurieren und verwalten können. Abbildung 1 zeigt ein Beispiel für ein Netzwerkdiagramm für ein Automobil:
Abbildung 1: Android Auto-Netzwerk
In diesem Bild sehen Sie, wie Ihre OEM-Netzwerk-App Methoden in der Klasse EthernetManager
aufruft, um Onboard-Ethernet-Netzwerke (eth0.1, eth0.2 und eth0.3) zu konfigurieren und zu verwalten. Der Rest von Abbildung 1 wird in diesem Dokument nicht behandelt.
Standard-Ethernet-Netzwerkeinstellungen festlegen
Verwenden Sie das Ressourcen-Overlay
config_ethernet_interfaces
, um Standardnetzwerkeinstellungen festzulegen:
<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>
In diesem Beispiel wird das config_ethernet_interfaces
-Ressourcen-Overlay aus config.xml
gezeigt.
Wichtige Punkte zum Code
eth1
,eth2
undeth3
sind die Namen der zu konfigurierenden Netzwerkschnittstelle.- Die fortlaufenden Zahlen von
12, 13, 14, 15
stehen für die Aktivierung von Netzwerkfunktionen. ip=
,gateway=
unddns
werden verwendet, um die anfängliche IP-Adresse, das Gateway und den DNS für das Netzwerk festzulegen.
Netzwerkschnittstelle aktivieren oder deaktivieren
Rufen Sie EthernetManager.enableInterface()
auf, um eine Netzwerkschnittstelle zu aktivieren:
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);
}
}
Wichtige Punkte zum Code
ifaceName
ist der Name der zu aktivierenden Netzwerkschnittstelle.getMainExecutor()
gibt den App-Kontext zurück.OutcomeReceiver
ist ein Callback, der verwendet wird, um den Abschluss zu kommunizieren. Bei Erfolg wird der aktualisierte Netzwerkname zurückgegeben, bei einem FehlerEthernetNetworkManagementException
.
Wenn eine Netzwerkschnittstelle aktiviert ist, werden die von EthernetManager.updateConfiguration()
festgelegten Einstellungen verwendet. Wenn eine Konfiguration nicht von EthernetManager.updateConfiguration()
festgelegt wurde, verwendet die Netzwerkschnittstelle das Ressourcen-Overlay config_ethernet_interfaces
oder die Standardkonfiguration für das Ethernet-Netzwerk, falls kein Overlay verfügbar ist.
Rufen Sie EthernetManager.disableInterface()
auf, um eine Netzwerkschnittstelle zu deaktivieren:
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);
}
}
Wichtige Punkte zum Code
ifaceName
ist der Name der Netzwerkschnittstelle, die deaktiviert werden soll.getMainExecutor()
gibt den App-Kontext zurück.OutcomeReceiver
ist ein Callback, der verwendet wird, um den Abschluss zu kommunizieren. Bei Erfolg wird der aktualisierte Netzwerkname zurückgegeben, bei einem FehlerEthernetNetworkManagementException
.
Netzwerkkonfiguration aktualisieren
So aktualisieren Sie Ethernet-Netzwerkkonfigurationen: Rufen Sie EthernetManager.updateConfiguration()
auf:
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);
}
}
Wichtige Punkte zum Code
getCapabilities()
ist eine Hilfsmethode, die die aktuellen Netzwerkfunktionen abruft undconvertToUIDs()
aufruft, um für Menschen lesbare Paketnamen in die eindeutige Linux-ID (UID) zu konvertieren. Normalerweise kennen Sie die UIDs für die zugehörigen Pakete nicht im Voraus. Wenn SieEthernetManager.updateConfiguration()
verwenden möchten, um den Zugriff auf eine Teilmenge von Apps zu beschränken, müssen Sie daher deren UIDs verwenden.request
ist die Konfiguration, die für das interne Netzwerk verwendet werden soll. Die Anfrage kann neue Einstellungen für die IP-Konfiguration und die Netzwerkfunktionen enthalten. Wenn das Netzwerk im Konnektivitäts-Stack registriert ist, wird es gemäß der Konfiguration aktualisiert. Diese Konfiguration bleibt nach einem Neustart nicht bestehen.getMainExecutor()
gibt den Executor zurück, auf dem der Listener aufgerufen wird.mCallback
ist der Callback, der verwendet wird, um den Abschluss zu kommunizieren. Bei Erfolg wird der aktualisierte Netzwerkname zurückgegeben, bei einem FehlerEthernetNetworkManagementException
.
updateConfiguration()
kann Merkmale eines Netzwerks aktualisieren, die vom Android-Verbindungs-Stack als unveränderlich betrachtet werden. Das Netzwerk wird heruntergefahren, aktualisiert und wieder hochgefahren, damit diese unveränderlichen Attribute aktualisiert werden können.
Netzwerk auf eine Teilmenge von Apps beschränken
Mit EthernetManager#updateConfiguration
können Sie den Zugriff auf eine Teilmenge der zulässigen UIDs beschränken. Verwenden Sie diese Methode für Anwendungsfälle, in denen dies erforderlich ist, z. B. für interne Fahrzeugnetzwerke, die nur von einer kleinen Teilmenge von OEM-Apps verwendet werden können.
Unter Android werden Apps in erster Linie anhand ihrer UID verfolgt.
Der folgende Code aus UIDToPackageNameConverter.java
zeigt, wie Sie eine Reihe von UIDs aus einem String mit Paketnamen abrufen:
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;
Wichtige Punkte zum Code
getApplicationInfoAsuser().uid
wird verwendet, um die UID aus dem Paketnamen abzurufen.uids
ist das generierte Array mit Ganzzahlen.
Der folgende Code in EthernetManagerTest.kt
zeigt, wie Sie die Konfiguration der Netzwerkschnittstelle mit den UIDs der Apps aktualisieren, die das Netzwerk verwenden dürfen:
val allowedUids = setOf(Process.myUid())
val nc = NetworkCapabilities.Builder(request.networkCapabilities)
.setAllowedUids(allowedUids).build()
updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
Wichtige Punkte zum Code
allowUids
ist die Gruppe der App-UIDs, die das Netzwerk verwenden dürfen.updateConfiguration()
aktualisiert die Konfiguration, um das Netzwerk auf die angegebene Gruppe von UIDs zu beschränken.