内部イーサネット ネットワークの構成

Android Auto OS 13 以降には、以下の機能が搭載されています 管理するためのツールです。図 1 は、ネットワークの例を示しています。 自動車の場合の図:

Android Auto ネットワーク

図 1. Android Auto ネットワーキング。

この図は、 オンボード イーサネット ネットワークを設定、管理するための 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 の連続した数字は、 ネットワーク 機能 有効にします。
  • ip=gateway=dns は、初期 IP アドレス、ゲートウェイ、 構成されます

ネットワーク インターフェースを有効または無効にする

ネットワーク インターフェースを有効にするには、 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 の固有識別子(UID)にマッピング。通常、 UID がわからない 事前購入する必要がありますそのため、Cloud Storage バケットを EthernetManager.updateConfiguration() でアクセスを一部のアプリに制限する場合、 使用する必要はありません。
  • request 内部ネットワークに使用する構成です「 IP 構成とネットワーク用の新しい設定を含めることができます。 提供しますもし ネットワークが接続スタックに登録されると、 できます。この構成は再起動後は保持されません。
  • getMainExecutor() は、リスナーが呼び出されたエグゼキュータを返します。
  • mCallback は、完了を伝えるために使用されるコールバックで、 ネットワーク名を更新(成功またはEthernetNetworkManagementException) エラーが発生します。

updateConfiguration() は、考慮されたネットワークの特性を更新することがあります Android 接続スタックによって変更できません。「 ネットワークが停止、更新、復旧されて、変更不可能なものが 指定します。

ネットワークをアプリのサブセットに制限する

EthernetManager#updateConfiguration を使用すると、アクセスを UID のサブセットのみです。次のようなユースケースには、この方法を使用します。 小規模なサブセットのみが使用できる社内車両ネットワークなど サポートします。

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 は、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 のセットです。