इंटरनल ईथरनेट नेटवर्क कॉन्फ़िगर करना

Android Auto OS 13 और उसके बाद के वर्शन में, ऐसी सुविधाएं मौजूद हैं जिनकी मदद से ईथरनेट नेटवर्क को कॉन्फ़िगर और मैनेज किया जा सकता है. पहली इमेज में, किसी वाहन के लिए नेटवर्क डायग्राम का उदाहरण दिया गया है:

Android Auto नेटवर्किंग

पहली इमेज. 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.xml से config_ethernet_interfaces संसाधन ओवरले दिखाया गया है.

कोड के बारे में अहम जानकारी

  • eth1, eth2, और eth3, कॉन्फ़िगर किए जा रहे नेटवर्क इंटरफ़ेस के नाम हैं.
  • 12, 13, 14, 15 के लगातार दिखने वाले नंबर, नेटवर्क की सुविधाओं के चालू होने की जानकारी देते हैं.
  • ip=, gateway=, और 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 एक कॉलबैक है. इसका इस्तेमाल, नेटवर्क का नाम अपडेट होने की जानकारी देने के लिए किया जाता है. नेटवर्क का नाम अपडेट होने पर, यह 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 एक कॉलबैक है. इसका इस्तेमाल, नेटवर्क का नाम अपडेट होने की जानकारी देने के लिए किया जाता है. नेटवर्क का नाम अपडेट होने पर, यह 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 पहले से नहीं पता होते. इसलिए, अगर आपको ऐप्लिकेशन के किसी सबसेट का ऐक्सेस सीमित करने के लिए EthernetManager.updateConfiguration() का इस्तेमाल करना है, तो आपको उनके यूआईडी का इस्तेमाल करना होगा.
  • request, इंटरनल नेटवर्क के लिए इस्तेमाल किया जाने वाला कॉन्फ़िगरेशन है. अनुरोध में, आईपी कॉन्फ़िगरेशन और नेटवर्क की सुविधाओं के लिए नई सेटिंग हो सकती हैं. अगर नेटवर्क को कनेक्टिविटी स्टैक के साथ रजिस्टर किया गया है, तो उसे कॉन्फ़िगरेशन के हिसाब से अपडेट किया जाता है. यह कॉन्फ़िगरेशन, रीबूट होने पर सेव नहीं रहता.
  • getMainExecutor(), उस एक्सेक्यूटर को दिखाता है जिस पर लिसनर को लागू किया जाता है.
  • mCallback एक कॉलबैक है. इसका इस्तेमाल, नेटवर्क का नाम अपडेट होने की जानकारी देने के लिए किया जाता है. अगर नेटवर्क का नाम अपडेट हो जाता है, तो यह कॉलबैक mCallback दिखाता है. अगर नेटवर्क का नाम अपडेट नहीं हो पाता है, तो यह कॉलबैक EthernetNetworkManagementException दिखाता है.

updateConfiguration(), ऐसे नेटवर्क की विशेषताओं को अपडेट कर सकता है जिसे Android कनेक्टिविटी स्टैक में बदलाव न करने वाला माना जाता है. बदले नहीं जा सकने वाले इन एट्रिब्यूट को अपडेट करने के लिए, नेटवर्क को बंद किया जाता है, अपडेट किया जाता है, और फिर से चालू किया जाता है.

किसी नेटवर्क को ऐप्लिकेशन के सबसेट पर सीमित करना

EthernetManager#updateConfiguration का इस्तेमाल करके, ऐक्सेस को सिर्फ़ अनुमति वाले UID के सबसेट तक सीमित किया जा सकता है. इस तरीके का इस्तेमाल उन इस्तेमाल के उदाहरणों के लिए करें जहां ऐसा करना ज़रूरी है. जैसे, वाहन के अंदर मौजूद नेटवर्क के लिए, जो सिर्फ़ OEM ऐप्लिकेशन के छोटे सबसेट का इस्तेमाल कर सकते हैं.

Android, मुख्य रूप से ऐप्लिकेशन को उनके यूआईडी के हिसाब से ट्रैक करता है. UIDToPackageNameConverter.java के नीचे दिए गए कोड में, पैकेज के नामों की स्ट्रिंग से यूआईडी की सीरीज़ पाने का तरीका बताया गया है:

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 में दिया गया यह कोड, नेटवर्क इंटरफ़ेस कॉन्फ़िगरेशन को अपडेट करने का तरीका दिखाता है. इसमें, नेटवर्क का इस्तेमाल करने की अनुमति वाले ऐप्लिकेशन के यूआईडी का इस्तेमाल किया गया है:

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

कोड के बारे में अहम जानकारी

  • allowUids, ऐप्लिकेशन के उन यूआईडी का सेट है जिन्हें नेटवर्क का इस्तेमाल करने की अनुमति है.
  • updateConfiguration(), कॉन्फ़िगरेशन को अपडेट करता है, ताकि नेटवर्क को यूआईडी के दिए गए सेट तक सीमित किया जा सके.