Mengonfigurasi jaringan Ethernet internal

Android Auto OS 13 dan yang lebih baru berisi fitur yang memungkinkan Anda mengonfigurasi dan mengelola jaringan Ethernet. Gambar 1 menunjukkan contoh diagram jaringan untuk mobil:

Jaringan Android Auto

Gambar 1. Jaringan Android Auto.

Gambar ini menunjukkan metode panggilan aplikasi jaringan OEM Anda di class EthernetManager untuk mengonfigurasi dan mengelola jaringan Ethernet onboard (eth0.1, eth0.2, dan eth0.3). Bagian lain dari Gambar 1 berada di luar cakupan dokumen ini.

Menetapkan setelan jaringan Ethernet default

Untuk menetapkan setelan jaringan default, gunakan overlay resource 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>

Contoh ini menunjukkan overlay resource config_ethernet_interfaces dari config.xml.

Poin penting tentang kode

  • eth1, eth2, dan eth3 adalah nama antarmuka jaringan yang sedang dikonfigurasi.
  • Angka 12, 13, 14, 15 berturut-turut mewakili kemampuan jaringan yang diaktifkan.
  • ip=, gateway=, dan dns digunakan untuk menetapkan alamat IP, gateway, dan DNS awal untuk jaringan.

Mengaktifkan atau menonaktifkan antarmuka jaringan

Untuk mengaktifkan antarmuka jaringan, panggil 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);
    }
}

Poin penting tentang kode

  • ifaceName adalah nama antarmuka jaringan yang akan diaktifkan.
  • getMainExecutor() menampilkan konteks aplikasi.
  • OutcomeReceiver adalah callback yang digunakan untuk menyampaikan penyelesaian yang menampilkan nama jaringan yang diperbarui jika berhasil atau EthernetNetworkManagementException jika terjadi error.

Saat diaktifkan, antarmuka jaringan akan menggunakan konfigurasi yang ditetapkan oleh EthernetManager.updateConfiguration(). Jika konfigurasi belum ditetapkan oleh EthernetManager.updateConfiguration(), antarmuka jaringan akan menggunakan overlay resource config_ethernet_interfaces atau konfigurasi jaringan Ethernet default jika overlay tidak tersedia.

Untuk menonaktifkan antarmuka jaringan, panggil 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);
    }
}

Poin penting tentang kode

  • ifaceName adalah nama antarmuka jaringan yang akan dinonaktifkan.
  • getMainExecutor() menampilkan konteks aplikasi.
  • OutcomeReceiver adalah callback yang digunakan untuk menyampaikan penyelesaian yang menampilkan nama jaringan yang diperbarui jika berhasil atau EthernetNetworkManagementException jika terjadi error.

Memperbarui konfigurasi jaringan

Untuk mengupdate konfigurasi jaringan Ethernet, panggil 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);

    }
}

Poin penting tentang kode

  • getCapabilities() adalah metode bantuan yang mendapatkan kemampuan jaringan saat ini dan memanggil convertToUIDs() untuk mengonversi nama paket yang dapat dibaca manusia menjadi ID unik (UID) Linux. Biasanya, Anda tidak mengetahui UID sebelumnya untuk paket terkait. Oleh karena itu, jika ingin menggunakan EthernetManager.updateConfiguration() untuk membatasi akses ke sebagian aplikasi, Anda harus menggunakan UID-nya.
  • request adalah konfigurasi yang akan digunakan untuk jaringan internal. Permintaan dapat berisi setelan baru untuk konfigurasi IP dan kemampuan jaringan. Jika terdaftar dengan stack konektivitas, jaringan akan diperbarui sesuai konfigurasi. Konfigurasi ini tidak akan berubah setelah perangkat dimulai ulang.
  • getMainExecutor() menampilkan eksekutor tempat pemroses dipanggil.
  • mCallback adalah callback yang digunakan untuk menyampaikan penyelesaian yang menampilkan nama jaringan yang diperbarui jika berhasil atau EthernetNetworkManagementException jika terjadi error.

updateConfiguration() dapat memperbarui karakteristik jaringan yang dianggap tidak dapat diubah oleh stack Android Connectivity. Jaringan dimatikan, diperbarui, dan diaktifkan kembali agar atribut yang tidak dapat diubah ini diperbarui.

Membatasi jaringan ke subkumpulan aplikasi

Anda dapat menggunakan EthernetManager#updateConfiguration untuk membatasi akses hanya ke sebagian UID yang diizinkan. Gunakan metode ini untuk mencakup kasus penggunaan yang diperlukan, seperti untuk jaringan kendaraan internal yang hanya dapat digunakan oleh sebagian kecil aplikasi OEM.

Android terutama melacak aplikasi berdasarkan UID-nya. Kode berikut dari UIDToPackageNameConverter.java menunjukkan cara mendapatkan serangkaian UID dari string nama paket:

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;

Poin penting tentang kode

  • getApplicationInfoAsuser().uid digunakan untuk mengambil UID dari nama paket.
  • uids adalah array bilangan bulat yang dihasilkan.

Kode berikut di EthernetManagerTest.kt menunjukkan cara memperbarui konfigurasi antarmuka jaringan dengan UID aplikasi yang diizinkan untuk menggunakan jaringan:

val allowedUids = setOf(Process.myUid())
        val nc = NetworkCapabilities.Builder(request.networkCapabilities)
                .setAllowedUids(allowedUids).build()
        updateConfiguration(iface, capabilities = nc).expectResult(iface.name)

Poin penting tentang kode

  • allowUids adalah kumpulan UID aplikasi yang diizinkan untuk menggunakan jaringan.
  • updateConfiguration() memperbarui konfigurasi untuk membatasi jaringan ke kumpulan UID yang disediakan.