Configura le reti Ethernet interne

Android Auto OS 13 e versioni successive contiene funzionalità che consentono di configurare e gestire le reti Ethernet. La Figura 1 mostra un esempio di rete diagramma per un'automobile:

Networking di Android Auto

Figura 1. Networking di Android Auto.

Questa figura mostra i metodi di chiamata dell'app di networking dell'OEM nella EthernetManager corso 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.

Configura le impostazioni di rete Ethernet predefinite

Per configurare le impostazioni di rete predefinite, utilizza overlay 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 un esempio mostra l'overlay della risorsa config_ethernet_interfaces di config.xml

Punti chiave sul codice

  • eth1, eth2 e eth3 sono i nomi dell'interfaccia di rete che viene configurata.
  • I numeri consecutivi di 12, 13, 14, 15 rappresentano rete funzionalità in fase di attivazione.
  • ip=, gateway= e dns vengono utilizzati per impostare l'indirizzo IP iniziale, il gateway e DNS per la rete.

Attivazione o disattivazione di 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 di rete aggiornato in caso di esito positivo o EthernetNetworkManagementException su .

Quando un'interfaccia di rete è abilitata, utilizza la configurazione impostata dalla EthernetManager.updateConfiguration(). Se non è stata impostata una configurazione da EthernetManager.updateConfiguration(), l'interfaccia di rete utilizza overlay di risorse config_ethernet_interfaces o la rete Ethernet predefinita se non è disponibile un overlay.

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 disabilitare.
  • getMainExecutor() restituisce il contesto dell'app.
  • OutcomeReceiver è un callback utilizzato per comunicare il completamento, restituendo il nome di rete aggiornato in caso di esito positivo o EthernetNetworkManagementException su .

Aggiorna configurazione di rete

Per aggiornare Configurazioni di rete Ethernet, chiamata 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 la rete funzionalità e chiama convertToUIDs() per convertire nomi dei pacchetti leggibili da una persona all'identificatore univoco (UID) Linux. Di solito, non conosco gli UID in anticipo per i pacchetti associati. Pertanto, se vuoi utilizzare EthernetManager.updateConfiguration() per limitare l'accesso a un sottoinsieme di app, devono utilizzare i rispettivi UID.
  • request è la configurazione da utilizzare per la rete interna. La può contenere nuove impostazioni per la configurazione IP e la le funzionalità di machine learning. Se sia registrata nello stack di connettività, viene aggiornata in base configurazione. Questa configurazione non viene mantenuta tra i riavvii.
  • getMainExecutor() restituisce l'esecutore su cui viene richiamato il listener.
  • mCallback è il callback utilizzato per comunicare il completamento, restituendo il nome di rete aggiornato in caso di esito positivo o EthernetNetworkManagementException su .

updateConfiguration() potrebbe aggiornare le caratteristiche di una rete considerata immutabili dallo stack della connettività Android. La la rete viene interrotta, aggiornata e ripristinata per queste immutabili attributi da aggiornare.

Limita una rete a un sottoinsieme di app

Puoi utilizzare EthernetManager#updateConfiguration per limitare l'accesso solo a un di UID consentiti. Utilizza questo metodo per coprire i casi d'uso in cui si tratta come richiesto, ad esempio per le reti veicolari interne utilizzabili solo da un piccolo sottoinsieme delle app degli OEM.

Android monitora principalmente le app in base al loro UID. Il seguente codice di UIDToPackageNameConverter.java mostra come ottenere una serie di UID da una stringa di nomi di pacchetto:

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().uid viene utilizzato per recuperare l'UID di dal il nome del pacchetto.
  • uids è l'array di numeri interi generati.

Il seguente codice EthernetManagerTest.kt mostra come aggiornare la configurazione dell'interfaccia di rete con gli UID delle app autorizzati 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)

Dove:

  • allowUids è l'insieme di UID dell'app a cui è consentito utilizzare la rete.
  • updateConfiguration() aggiorna la configurazione per limitare la rete a l'insieme di UID fornito.