Android Auto OS 13 y versiones posteriores contienen funciones que te permiten configurar y administrar redes Ethernet. En la Figura 1, se muestra un ejemplo de un diagrama de red para un automóvil:
 
 
Figura 1: Redes de Android Auto
En esta figura, se muestra tu app de redes del OEM llamando a métodos en la clase EthernetManager para configurar y administrar redes Ethernet integradas (eth0.1, eth0.2 y eth0.3). El resto de la Figura 1 está fuera del alcance de este documento.
Cómo establecer la configuración de red Ethernet predeterminada
Para establecer la configuración de red predeterminada, usa la superposición de recursos
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>
En este ejemplo, se muestra la superposición de recursos config_ethernet_interfaces de config.xml.
Puntos clave sobre el código
- eth1,- eth2y- eth3son los nombres de la interfaz de red que se está configurando.
- Los números consecutivos de 12, 13, 14, 15representan las capacidades de red que se habilitan.
- ip=,- gateway=y- dnsse usan para establecer la dirección IP, la puerta de enlace y el DNS iniciales de la red.
Cómo habilitar o inhabilitar una interfaz de red
Para habilitar una interfaz de red, llama a 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);
    }
}
Puntos clave sobre el código
- ifaceNamees el nombre de la interfaz de red que se habilitará.
- getMainExecutor()devuelve el contexto de la app.
- OutcomeReceiveres una devolución de llamada que se usa para comunicar la finalización y que devuelve el nombre de la red actualizado si se realiza correctamente o- EthernetNetworkManagementExceptionsi se produce un error.
Cuando se habilita una interfaz de red, se usa la configuración establecida por EthernetManager.updateConfiguration(). Si EthernetManager.updateConfiguration() no estableció una configuración, la interfaz de red usa la superposición de recursos config_ethernet_interfaces o la configuración de red Ethernet predeterminada si no hay una superposición disponible.
Para inhabilitar una interfaz de red, llama a 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);
    }
}
Puntos clave sobre el código
- ifaceNamees el nombre de la interfaz de red que se inhabilitará.
- getMainExecutor()devuelve el contexto de la app.
- OutcomeReceiveres una devolución de llamada que se usa para comunicar la finalización y que devuelve el nombre de la red actualizado si se realiza correctamente o- EthernetNetworkManagementExceptionsi se produce un error.
Actualiza la configuración de red
Para actualizar la configuración de red Ethernet, llama a 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);
    }
}
Puntos clave sobre el código
- getCapabilities()es un método auxiliar que obtiene las capacidades de red actuales y llama a- convertToUIDs()para convertir los nombres de paquetes legibles por humanos en un identificador único (UID) de Linux. Por lo general, no conoces los UIDs de antemano para sus paquetes asociados. Por lo tanto, si quieres usar- EthernetManager.updateConfiguration()para limitar el acceso a un subconjunto de apps, debes usar sus UIDs.
- requestes la configuración que se usará para la red interna. La solicitud puede contener una nueva configuración para la configuración de IP y las capacidades de red. Si la red está registrada en la pila de conectividad, se actualiza según la configuración. Esta configuración no persiste durante los reinicios.
- getMainExecutor()devuelve el ejecutor en el que se invoca el objeto de escucha.
- mCallbackes la devolución de llamada que se usa para comunicar la finalización y que devuelve el nombre de la red actualizado si se realiza correctamente o- EthernetNetworkManagementExceptionsi se produce un error.
updateConfiguration() podría actualizar las características de una red que la pila de conectividad de Android considera inmutables. La red se desactiva, se actualiza y se vuelve a activar para que se actualicen estos atributos inmutables.
Cómo restringir una red a un subconjunto de apps
Puedes usar EthernetManager#updateConfiguration para limitar el acceso solo a un subconjunto de los UIDs permitidos. Usa este método para abarcar casos de uso en los que esto es necesario, como para redes vehiculares internas que solo puede usar un pequeño subconjunto de apps del OEM.
Android principalmente hace un seguimiento de las apps por su UID.
El siguiente código de UIDToPackageNameConverter.java muestra cómo obtener una serie de UID a partir de una cadena de nombres de paquetes:
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;
Puntos clave sobre el código
- getApplicationInfoAsuser().uidse usa para recuperar el UID del nombre del paquete.
- uidses el array de números enteros generado.
El siguiente código en EthernetManagerTest.kt muestra cómo actualizar la configuración de la interfaz de red con los UID de las apps que pueden usar la red:
val allowedUids = setOf(Process.myUid())
        val nc = NetworkCapabilities.Builder(request.networkCapabilities)
                .setAllowedUids(allowedUids).build()
        updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
Puntos clave sobre el código
- allowUidses el conjunto de UID de la app que pueden usar la red.
- updateConfiguration()actualiza la configuración para restringir la red al conjunto de UIDs proporcionado.
