Định cấu hình mạng Ethernet nội bộ

Android Auto OS 13 trở lên có các tính năng cho phép bạn định cấu hình và quản lý mạng Ethernet. Hình 1 cho thấy sơ đồ mạng mẫu cho một ô tô:

Kết nối mạng Android Auto

Hình 1. Kết nối mạng Android Auto.

Hình này cho thấy các phương thức gọi ứng dụng kết nối mạng của OEM trong lớp EthernetManager để định cấu hình và quản lý mạng Ethernet trên bo mạch (eth0.1, eth0.2 và eth0.3). Phần còn lại của Hình 1 nằm ngoài phạm vi của tài liệu này.

Đặt chế độ cài đặt mạng Ethernet mặc định

Để đặt chế độ cài đặt mạng mặc định, hãy sử dụng lớp phủ tài nguyên 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>

Ví dụ này cho thấy lớp phủ tài nguyên config_ethernet_interfaces từ config.xml.

Các điểm chính về mã

  • eth1, eth2eth3 là tên của giao diện mạng đang được định cấu hình.
  • Các số liên tiếp của 12, 13, 14, 15 đại diện cho các tính năng mạng đang được bật.
  • ip=, gateway=dns được dùng để đặt địa chỉ IP, cổng và DNS ban đầu cho mạng.

Bật hoặc tắt giao diện mạng

Để bật giao diện mạng, hãy gọi 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);
    }
}

Các điểm chính về mã

  • ifaceName là tên của giao diện mạng cần bật.
  • getMainExecutor() trả về ngữ cảnh ứng dụng.
  • OutcomeReceiver là lệnh gọi lại dùng để thông báo việc hoàn tất, trả về tên mạng đã cập nhật nếu thành công hoặc EthernetNetworkManagementException nếu xảy ra lỗi.

Khi được bật, giao diện mạng sẽ sử dụng cấu hình do EthernetManager.updateConfiguration() đặt. Nếu EthernetManager.updateConfiguration() chưa đặt cấu hình, giao diện mạng sẽ sử dụng lớp phủ tài nguyên config_ethernet_interfaces hoặc cấu hình mạng Ethernet mặc định nếu không có lớp phủ.

Để tắt giao diện mạng, hãy gọi 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);
    }
}

Các điểm chính về mã

  • ifaceName là tên của giao diện mạng cần tắt.
  • getMainExecutor() trả về ngữ cảnh ứng dụng.
  • OutcomeReceiver là lệnh gọi lại dùng để thông báo việc hoàn tất, trả về tên mạng đã cập nhật nếu thành công hoặc EthernetNetworkManagementException nếu xảy ra lỗi.

Cập nhật cấu hình mạng

Để cập nhật cấu hình mạng Ethernet, hãy gọi 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);

    }
}

Các điểm chính về mã

  • getCapabilities() là một phương thức trợ giúp nhận các chức năng mạng hiện tại và gọi convertToUIDs() để chuyển đổi tên gói mà con người có thể đọc được thành giá trị nhận dạng duy nhất (UID) của Linux. Thông thường, bạn không biết trước UID cho các gói liên kết. Do đó, nếu muốn sử dụng EthernetManager.updateConfiguration() để giới hạn quyền truy cập vào một nhóm ứng dụng, bạn cần sử dụng UID của các ứng dụng đó.
  • request là cấu hình sẽ được dùng cho mạng nội bộ. Yêu cầu này có thể chứa chế độ cài đặt mới cho cấu hình IP và các tính năng mạng. Nếu mạng được đăng ký với ngăn xếp kết nối, thì mạng đó sẽ được cập nhật theo cấu hình. Cấu hình này không được duy trì sau khi khởi động lại.
  • getMainExecutor() trả về trình thực thi mà trình nghe được gọi.
  • mCallback là lệnh gọi lại dùng để thông báo việc hoàn tất, trả về tên mạng đã cập nhật nếu thành công hoặc EthernetNetworkManagementException nếu gặp lỗi.

updateConfiguration() có thể cập nhật các đặc điểm của một mạng được ngăn xếp Khả năng kết nối Android coi là không thể thay đổi. Mạng sẽ bị tắt, cập nhật và bật lại để cập nhật các thuộc tính không thể thay đổi này.

Hạn chế một mạng cho một nhóm nhỏ ứng dụng

Bạn có thể sử dụng EthernetManager#updateConfiguration để chỉ giới hạn quyền truy cập vào một nhóm nhỏ UID được phép. Sử dụng phương thức này cho các trường hợp sử dụng bắt buộc, chẳng hạn như đối với mạng ô tô nội bộ chỉ một số ít ứng dụng OEM mới có thể sử dụng.

Android chủ yếu theo dõi các ứng dụng theo UID của ứng dụng. Mã sau đây từ UIDToPackageNameConverter.java cho biết cách lấy một loạt UID từ một chuỗi tên gói:

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;

Các điểm chính về mã

  • getApplicationInfoAsuser().uid được dùng để truy xuất UID từ tên gói.
  • uids là mảng số nguyên được tạo.

Mã sau đây trong EthernetManagerTest.kt cho biết cách cập nhật cấu hình giao diện mạng bằng UID của các ứng dụng được phép sử dụng mạng:

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

Các điểm chính về mã

  • allowUids là tập hợp các UID ứng dụng được phép sử dụng mạng.
  • updateConfiguration() cập nhật cấu hình để hạn chế mạng ở nhóm UID được cung cấp.