設定內部乙太網路

Android Auto OS 13 以上版本提供以下功能: 設定及管理乙太網路圖 1 顯示了網路範例 圖表:

Android Auto 網路

圖 1. Android Auto 網路。

這張圖片顯示 OEM 網路應用程式的呼叫方法, EthernetManager 類別,用於設定及管理內建乙太網路 (eth0.1、eth0.2 和 eth0.3)。圖 1 的其餘部分超出 本文件。

設定預設乙太網路設定

如要設定預設聯播網設定,請使用 資源重疊 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>

這個 範例顯示config_ethernet_interfaces config.xml

程式碼相關重點

  • eth1eth2eth3 是目前設定的網路介面名稱。
  • 12, 13, 14, 15 的連續數字代表 聯播網 技術能力 正在啟用的 Pod
  • ip=gateway=dns 是用來設定初始 IP 位址、閘道、 網路也設有 DNS

啟用或停用網路介面

如要啟用網路介面,請呼叫 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);
    }
}

程式碼相關重點

  • ifaceName 是要啟用的網路介面名稱。
  • getMainExecutor() 會傳回應用程式結構定義。
  • OutcomeReceiver 是一種回呼,用來傳達可傳回 成功更新網路名稱,或於 EthernetNetworkManagementException 錯誤。

啟用網路介面時,介面會使用 EthernetManager.updateConfiguration()。如果未設定 由 EthernetManager.updateConfiguration() 建立,網路介面會使用 資源重疊 config_ethernet_interfaces 或預設乙太網路 。

如要停用網路介面,請呼叫 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);
    }
}

程式碼相關重點

  • ifaceName 是要停用的網路介面名稱。
  • getMainExecutor() 會傳回應用程式結構定義。
  • OutcomeReceiver 是一種回呼,用來傳達可傳回 成功更新網路名稱,或於 EthernetNetworkManagementException 錯誤。

更新網路設定

更新 乙太網路網路設定,呼叫 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);

    }
}

程式碼相關重點

  • getCapabilities() 是一種輔助方法,以取得目前的網路 功能,並呼叫 convertToUIDs() 完成轉換 使用者容易理解的 Linux 專屬 ID (UID) 套件名稱。一般而言, 不知道 UID 將其相關聯的套件開放因此,如果要 EthernetManager.updateConfiguration(),就能限制只有部分應用程式的存取權 需使用 UID
  • request 是內部網路要使用的設定。 要求可包含 IP 設定和網路的新設定 即便沒有技術背景,也能因這些工具的功能而受益如果 網路註冊已根據連線堆疊 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定重新啟動後不會保留這項設定。
  • getMainExecutor() 會傳回叫用事件監聽器的執行器。
  • mCallback 是用來傳送可傳回 成功更新網路名稱,或於 EthernetNetworkManagementException 錯誤。

updateConfiguration() 可能會更新考慮的網路特性 無法由 Android 連線堆疊變更。 中斷、更新並復原這些不可變動的網路 屬性。

將網路限制為部分應用程式

您可以使用 EthernetManager#updateConfiguration,限制只有特定使用者才能使用 部分 UID。使用這個方法可涵蓋 例如內部車輛網路 (只有少數人可使用) 原始設備製造商 (OEM) 應用程式

Android 主要是透過 UID 追蹤應用程式。 下列程式碼 UIDToPackageNameConverter.java 顯示如何從套件名稱字串取得一系列 UID:

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;

程式碼相關重點

  • getApplicationInfoAsuser().uid 是用來從 套件名稱。
  • uids 是產生的整數陣列。

EthernetManagerTest.kt 顯示如何使用應用程式的 UID 更新網路介面設定 可以使用網路:

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

地點:

  • allowUids 是可使用網路的應用程式 UID 組合。
  • updateConfiguration() 會更新設定,將網路限制為 提供的 UID