Android Automotive OS 13 et versions ultérieures contiennent des fonctionnalités qui vous permettent de configurer et de gérer les réseaux Ethernet. La figure 1 montre un exemple de schéma de réseau pour une automobile :
Figure 1 : Mise en réseau Android Auto.
Cette figure montre votre application réseau OEM appelant des méthodes dans la classe EthernetManager pour configurer et gérer les réseaux Ethernet embarqués (eth0.1, eth0.2 et eth0.3). Le reste de la figure 1 ne relève pas de ce document.
Définir les paramètres réseau Ethernet par défaut
Pour définir les paramètres réseau par défaut, utilisez le fichier de superposition de ressources
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>
Cet exemple montre la superposition de ressources config_ethernet_interfaces à partir de config.xml.
Points clés concernant le code
eth1,eth2eteth3sont les noms des interfaces réseau en cours de configuration.- Les nombres consécutifs de
12, 13, 14, 15représentent les fonctionnalités réseau activées. ip=,gateway=etdnspermettent de définir l'adresse IP, la passerelle et le DNS initiaux pour le réseau.
Activer ou désactiver une interface réseau
Pour activer une interface réseau, appelez 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);
}
}
Points clés concernant le code
ifaceNamecorrespond au nom de l'interface réseau à activer.getMainExecutor()renvoie le contexte de l'application.OutcomeReceiverest un rappel utilisé pour communiquer la fin de l'opération, en renvoyant le nom du réseau mis à jour en cas de succès ouEthernetNetworkManagementExceptionen cas d'erreur.
Lorsqu'une interface réseau est activée, elle utilise la configuration définie par EthernetManager.updateConfiguration(). Si EthernetManager.updateConfiguration() n'a pas défini de configuration, l'interface réseau utilise la superposition de ressources config_ethernet_interfaces ou la configuration réseau Ethernet par défaut si aucune superposition n'est disponible.
Pour désactiver une interface réseau, appelez 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);
}
}
Points clés concernant le code
ifaceNamecorrespond au nom de l'interface réseau à désactiver.getMainExecutor()renvoie le contexte de l'application.OutcomeReceiverest un rappel utilisé pour communiquer la fin de l'opération, en renvoyant le nom du réseau mis à jour en cas de succès ouEthernetNetworkManagementExceptionen cas d'erreur.
Mettre à jour la configuration réseau
Pour mettre à jour les configurations du réseau Ethernet, appelez 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);
}
}
Points clés concernant le code
getCapabilities()est une méthode d'assistance qui obtient les capacités réseau actuelles et appelleconvertToUIDs()pour convertir les noms de packages lisibles par l'homme en identifiant unique (UID) Linux. En général, vous ne connaissez pas à l'avance les UID de leurs packages associés. Par conséquent, si vous souhaitez utiliserEthernetManager.updateConfiguration()pour limiter l'accès à un sous-ensemble d'applications, vous devez utiliser leurs UID.requestcorrespond à la configuration à utiliser pour le réseau interne. La requête peut contenir de nouveaux paramètres pour la configuration IP et les capacités réseau. Si le réseau est enregistré auprès de la pile de connectivité, il est mis à jour conformément à la configuration. Cette configuration ne persiste pas lors des redémarrages.getMainExecutor()renvoie l'exécuteur sur lequel l'écouteur est appelé.mCallbackest le rappel utilisé pour communiquer la fin de l'opération, en renvoyant le nom du réseau mis à jour en cas de succès ouEthernetNetworkManagementExceptionen cas d'erreur.
updateConfiguration() peut mettre à jour les caractéristiques d'un réseau considéré comme immuable par la pile de connectivité Android. Le réseau est mis hors service, mis à jour et remis en service pour que ces attributs immuables soient mis à jour.
Restreindre un réseau à un sous-ensemble d'applications
Vous pouvez utiliser EthernetManager#updateConfiguration pour limiter l'accès à un sous-ensemble d'UID autorisés. Utilisez cette méthode pour couvrir les cas d'utilisation où cela est nécessaire, par exemple pour les réseaux de véhicules internes utilisables uniquement par un petit sous-ensemble d'applications OEM.
Android suit principalement les applications par leur UID.
Le code suivant de UIDToPackageNameConverter.java montre comment obtenir une série d'UID à partir d'une chaîne de noms de packages :
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;
Points clés concernant le code
getApplicationInfoAsuser().uidpermet de récupérer l'UID à partir du nom du package.uidsest le tableau d'entiers généré.
Le code suivant dans EthernetManagerTest.kt montre comment mettre à jour la configuration de votre interface réseau avec les UID des applications autorisées à utiliser le réseau :
val allowedUids = setOf(Process.myUid())
val nc = NetworkCapabilities.Builder(request.networkCapabilities)
.setAllowedUids(allowedUids).build()
updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
Points clés concernant le code
allowUidsest l'ensemble des UID d'application autorisés à utiliser le réseau.updateConfiguration()met à jour la configuration pour limiter le réseau à l'ensemble d'UID fourni.