Android Auto OS 13 e versioni successive contengono funzionalità che consentono di configurare e gestire le reti Ethernet. La Figura 1 mostra un diagramma di rete di esempio per un'automobile:
Figura 1. Networking di Android Auto.
Questa figura mostra la tua app di networking OEM che chiama i metodi nella classe EthernetManager per configurare e gestire le reti Ethernet integrate (eth0.1, eth0.2 ed eth0.3). Il resto della Figura 1 non rientra nell'ambito di questo documento.
Impostare le impostazioni della rete Ethernet predefinite
Per impostare le impostazioni della rete predefinite, utilizza la
sovrapposizione delle risorse
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>
Questo
esempio mostra la sovrapposizione delle risorse config_ethernet_interfaces da
config.xml.
Punti chiave sul codice
eth1,eth2eeth3sono i nomi dell'interfaccia di rete in fase di configurazione.- I numeri consecutivi
12, 13, 14, 15rappresentano funzionalità di rete in fase di attivazione. ip=,gateway=ednsvengono utilizzati per impostare l'indirizzo IP, il gateway e il DNS iniziali per la rete.
Attivare o disattivare un'interfaccia di rete
Per attivare un'interfaccia di rete, chiama
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);
}
}
Punti chiave sul codice
ifaceNameè il nome dell'interfaccia di rete da attivare.getMainExecutor()restituisce il contesto dell'app.OutcomeReceiverè un callback utilizzato per comunicare il completamento, restituendo il nome della rete aggiornato in caso di esito positivo oEthernetNetworkManagementExceptionin caso di errore.
Quando un'interfaccia di rete è attiva, utilizza la configurazione impostata da EthernetManager.updateConfiguration(). Se non è stata impostata una configurazione da EthernetManager.updateConfiguration(), l'interfaccia di rete utilizza la sovrapposizione delle risorse config_ethernet_interfaces o la configurazione di rete Ethernet predefinita se non è disponibile una sovrapposizione.
Per disattivare un'interfaccia di rete, chiama
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);
}
}
Punti chiave sul codice
ifaceNameè il nome dell'interfaccia di rete da disattivare.getMainExecutor()restituisce il contesto dell'app.OutcomeReceiverè un callback utilizzato per comunicare il completamento, restituendo il nome della rete aggiornato in caso di esito positivo oEthernetNetworkManagementExceptionin caso di errore.
Aggiornare la configurazione di rete
Per aggiornare
le configurazioni di rete Ethernet, chiama
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);
}
}
Punti chiave sul codice
getCapabilities()è un metodo helper che recupera le funzionalità di rete attuali e chiamaconvertToUIDs()per convertire i nomi dei pacchetti leggibili in identificatori univoci (UID) Linux. In genere, non conosci in anticipo gli UID dei pacchetti associati. Pertanto, se vuoi utilizzareEthernetManager.updateConfiguration()per limitare l'accesso a un sottoinsieme di app, devi utilizzare i relativi UID.requestè la configurazione da utilizzare per la rete interna. La richiesta può contenere una nuova impostazione per la configurazione IP e le funzionalità di rete. Se la rete è registrata nello stack di connettività, viene aggiornata in base alla configurazione. Questa configurazione non viene mantenuta dopo i riavvii.getMainExecutor()restituisce l'executor su cui viene richiamato il listener.mCallbackè il callback utilizzato per comunicare il completamento, restituendo il nome della rete aggiornato in caso di esito positivo oEthernetNetworkManagementExceptionin caso di errore.
updateConfiguration() potrebbe aggiornare le caratteristiche di una rete considerata immutabile dallo stack di connettività Android. Per aggiornare questi attributi immutabili, la rete viene disattivata, aggiornata e riattivata.
Limitare una rete a un sottoinsieme di app
Puoi utilizzare EthernetManager#updateConfiguration per limitare l'accesso solo a un
sottoinsieme di UID consentiti. Utilizza questo metodo per coprire i casi d'uso in cui è
necessario, ad esempio per le reti veicolari interne utilizzabili solo da un piccolo sottoinsieme
di app OEM.
Android tiene traccia principalmente delle app in base al loro UID.
Il seguente codice da
UIDToPackageNameConverter.java
mostra come ottenere una serie di UID da una stringa di nomi di pacchetti:
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;
Punti chiave sul codice
getApplicationInfoAsuser().uidviene utilizzato per recuperare l'UID dal nome del pacchetto.uidsè l'array di numeri interi generato.
Il seguente codice in
EthernetManagerTest.kt
mostra come aggiornare la configurazione dell'interfaccia di rete con gli UID delle app
autorizzate a utilizzare la rete:
val allowedUids = setOf(Process.myUid())
val nc = NetworkCapabilities.Builder(request.networkCapabilities)
.setAllowedUids(allowedUids).build()
updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
Punti chiave sul codice
allowUidsè l'insieme degli UID delle app autorizzate a utilizzare la rete.updateConfiguration()aggiorna la configurazione per limitare la rete all'insieme di UID fornito.