Dahili Ethernet ağlarını yapılandırma

Android Auto OS 13 ve sonraki sürümlerde Ethernet ağlarını yapılandırmanıza ve yönetmenize olanak tanıyan özellikler bulunur. Şekil 1'de bir otomobile ait örnek ağ şeması gösterilmektedir:

Android Auto ağ bağlantısı

1. şekil. Android Auto ağ bağlantısı.

Bu şekil, yerleşik Ethernet ağlarını (eth0.1, eth0.2 ve eth0.3) yapılandırmak ve yönetmek için EthernetManager sınıfındaki OEM ağ uygulaması çağırma yöntemlerinizi gösterir. Şekil 1'in geri kalanı bu belgenin kapsamı dışındadır.

Varsayılan Ethernet ağ ayarlarını belirleme

Varsayılan ağ ayarlarını belirlemek için kaynak yer paylaşımını kullanı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>

Bu örnekte, config.xml'daki config_ethernet_interfaces kaynak yerleşimi gösterilmektedir.

Kodla ilgili önemli noktalar

  • eth1, eth2 ve eth3, yapılandırılan ağ arayüzünün adlarıdır.
  • 12, 13, 14, 15 ardışık sayıları, ağ özelliklerinin etkinleştirildiğini gösterir.
  • ip=, gateway= ve dns, ağ için ilk IP adresini, ağ geçidini ve DNS'yi ayarlamak üzere kullanılır.

Ağ arayüzünü etkinleştirme veya devre dışı bırakma

Bir ağ arayüzünü etkinleştirmek için EthernetManager.enableInterface() komutunu çağırın:

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);
    }
}

Kodla ilgili önemli noktalar

  • ifaceName etkinleştirilecek ağ arayüzünün adıdır.
  • getMainExecutor(), uygulama bağlamını döndürür.
  • OutcomeReceiver, tamamlanma durumunu bildirmek için kullanılan bir geri çağırma işlevidir. İşlem başarılı olduğunda güncellenen ağ adını, hata durumunda ise EthernetNetworkManagementException değerini döndürür.

Bir ağ arayüzü etkinleştirildiğinde EthernetManager.updateConfiguration() tarafından ayarlanan yapılandırma kullanılır. EthernetManager.updateConfiguration() tarafından bir yapılandırma ayarlanmamışsa ağ arayüzü, kaynak yer paylaşımını config_ethernet_interfaces veya yer paylaşımı yoksa varsayılan Ethernet ağı yapılandırmasını kullanır.

Bir ağ arayüzünü devre dışı bırakmak için EthernetManager.disableInterface() işlevini çağırın:

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);
    }
}

Kodla ilgili önemli noktalar

  • ifaceName, devre dışı bırakılacak ağ arayüzünün adıdır.
  • getMainExecutor(), uygulama bağlamını döndürür.
  • OutcomeReceiver, tamamlanma durumunu bildirmek için kullanılan bir geri çağırma işlevidir. İşlem başarılı olduğunda güncellenen ağ adını, hata durumunda ise EthernetNetworkManagementException değerini döndürür.

Ağ yapılandırmasını güncelleme

Ethernet ağ yapılandırmalarını güncellemek için EthernetManager.updateConfiguration() işlevini çağırın:

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);

    }
}

Kodla ilgili önemli noktalar

  • getCapabilities() mevcut ağ özelliklerini alan ve okunabilir paket adlarını Linux benzersiz tanımlayıcısına (UID) dönüştürmek için convertToUIDs() yöntemini çağıran yardımcı bir yöntemdir. Genellikle, ilişkili paketlerin UID'lerini önceden bilmezsiniz. Bu nedenle, erişimi bir uygulama alt kümesiyle sınırlamak için EthernetManager.updateConfiguration() kullanmak istiyorsanız bu uygulamaların UID'lerini kullanmanız gerekir.
  • request dahili ağ için kullanılacak yapılandırmadır. İstek, IP yapılandırması ve ağ özellikleri için yeni ayarlar içerebilir. Ağ, bağlantı yığınına kaydedilmişse yapılandırmaya göre güncellenir. Bu yapılandırma, yeniden başlatma işlemlerinde kalıcı olmaz.
  • getMainExecutor(), dinleyicinin çağrıldığı yürütücüyü döndürür.
  • mCallback, tamamlanma durumunu bildirmek için kullanılan geri aramadır. İşlem başarılı olduğunda güncellenen ağ adını, hata durumunda ise EthernetNetworkManagementException değerini döndürür.

updateConfiguration(), Android Bağlantı yığını tarafından değişmez olarak kabul edilen bir ağın özelliklerini güncelleyebilir. Ağ, bu değişmez özelliklerin güncellenmesi için kapatılır, güncellenir ve yeniden açılır.

Bir ağı uygulamaların bir alt grubuyla kısıtlama

Erişimi yalnızca izin verilen UID'lerin bir alt kümesiyle sınırlamak için EthernetManager#updateConfiguration kullanabilirsiniz. Bu yöntemi, yalnızca OEM uygulamalarının küçük bir alt kümesi tarafından kullanılabilen dahili araç ağları gibi bu durumun gerekli olduğu kullanım alanlarını kapsamak için kullanın.

Android, uygulamaları öncelikli olarak UID'lerine göre izler. UIDToPackageNameConverter.java adresindeki aşağıdaki kodda, paket adı dizesinden bir dizi UID'nin nasıl alınacağı gösterilmektedir:

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;

Kodla ilgili önemli noktalar

  • getApplicationInfoAsuser().uid, paket adından UID'yi almak için kullanılır.
  • uids, oluşturulan tam sayı dizisidir.

EthernetManagerTest.kt bölümündeki aşağıdaki kodda, ağ arayüzü yapılandırmanızı ağın kullanılmasına izin verilen uygulamaların UID'leriyle nasıl güncelleyeceğiniz gösterilmektedir:

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

Kodla ilgili önemli noktalar

  • allowUids, ağı kullanmasına izin verilen uygulama UID'lerinin kümesidir.
  • updateConfiguration(), yapılandırmayı güncelleyerek ağı sağlanan UID'ler grubuyla kısıtlar.