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

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

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

पहली इमेज. Android Auto नेटवर्किंग.

इस इमेज में, EthernetManager क्लास में ओईएम नेटवर्किंग ऐप्लिकेशन की कॉलिंग के तरीके दिखाए गए हैं. इनका इस्तेमाल, बोर्ड पर मौजूद ईथरनेट नेटवर्क (eth0.1, eth0.2, और eth0.3) को कॉन्फ़िगर और मैनेज करने के लिए किया जाता है. इस दस्तावेज़ में, पहले फ़िगर के बाकी हिस्से के बारे में जानकारी नहीं दी गई है.

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

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

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

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

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

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(), कॉन्फ़िगरेशन को अपडेट करता है, ताकि नेटवर्क को दिए गए यूआईडी के सेट तक सीमित किया जा सके.