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

Android Auto OS 13 ve sonraki sürümler, Ethernet ağlarını yapılandırmanıza ve yönetmenize olanak tanıyan özellikler içerir. Şekil 1'de bir otomobil için örnek bir ağ şeması gösterilmektedir:

Android Auto ağ bağlantısı

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

Bu şekil, OEM ağ uygulamanızın 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 yöntemleri çağırmasını gösterir. Şekil 1'in geri kalanı bu dokümanın kapsamı dışındadır.

Varsayılan Ethernet ağ ayarlarını belirleme

Varsayılan ağ ayarlarını belirlemek için kaynak yer paylaşımını config_ethernet_interfaces kullanın:

<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 kaynağındaki config_ethernet_interfaces kaynak yer paylaşımı gösterilmektedir.

Kodla ilgili önemli noktalar

  • eth1, eth2 ve eth3, yapılandırılan ağ arayüzünün adlarıdır.
  • Art arda gelen 12, 13, 14, 15 sayıları, ağ özelliklerinin etkinleştirildiğini gösterir.
  • ip=, gateway= ve dns, ağın ilk IP adresini, ağ geçidini ve DNS'sini ayarlamak için 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() simgesini tıklayı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, işlemin tamamlandığını bildirmek için kullanılan bir geri çağırma işlevidir. İşlem başarılı olursa güncellenmiş ağ adını, aksi takdirde EthernetNetworkManagementException değerini döndürür.

Bir ağ arayüzü etkinleştirildiğinde EthernetManager.updateConfiguration() tarafından ayarlanan yapılandırmayı kullanı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() çağrısı yapı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, işlemin tamamlandığını bildirmek için kullanılan bir geri çağırma işlevidir. İşlem başarılı olursa güncellenmiş ağ adını, aksi takdirde 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 arayı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(), geçerli ağ özelliklerini alan ve kullanıcı tarafından okunabilen paket adlarını Linux benzersiz tanımlayıcısına (UID) dönüştürmek için convertToUIDs()'ı çağıran bir yardımcı yöntemdir. Genellikle, ilişkili paketlerin UID'lerini önceden bilmezsiniz. Bu nedenle, bir uygulama alt kümesine erişimi sınırlamak için EthernetManager.updateConfiguration() kullanmak istiyorsanız uygulama 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şlatmalarda korunmaz.
  • getMainExecutor(), dinleyicinin çağrıldığı yürütücüyü döndürür.
  • mCallback, işlemin tamamlandığını bildirmek için kullanılan geri çağırma işlevidir. İşlem başarılı olursa güncellenmiş ağ adını, aksi takdirde EthernetNetworkManagementException değerini döndürür.

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

Bir ağı bir uygulama alt kümesiyle kısıtlama

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

Android, uygulamaları öncelikle UID'lerine göre izler. UIDToPackageNameConverter.java kaynaklı aşağıdaki kodda, bir paket adı dizesinden nasıl bir dizi UID elde edileceği 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 kod, ağ arayüzü yapılandırmanızı ağı kullanmaya izin verilen uygulamaların UID'leriyle nasıl güncelleyeceğinizi gösterir:

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'leri kümesidir.
  • updateConfiguration(), yapılandırmayı ağı sağlanan UID kümesiyle kısıtlamak için günceller.