إعداد شبكات إيثرنت الداخلية

يتضمّن الإصدار 13 من نظام التشغيل Android Auto والإصدارات الأحدث ميزات تتيح لك ضبط شبكات Ethernet وإدارتها. يعرض الشكل 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.

النقاط الرئيسية حول الرمز

  • eth1 وeth2 وeth3 هي أسماء واجهة الشبكة التي يتم ضبطها.
  • تشير الأرقام المتسلسلة 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 أو الإعدادات التلقائية لشبكة Ethernet إذا لم يكن تداخل متاحًا.

لإيقاف واجهة شبكة، يمكنك الاتصال بـ 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() لتحويل أسماء الحِزم القابلة للقراءة من قِبل المستخدمين إلى المعرّف الفريد (UID) في نظام التشغيل Linux. عادةً ما لا تعرف معرّفات UID مسبقًا للحِزم المرتبطة بها. لذلك، إذا كنت تريد استخدام EthernetManager.updateConfiguration() لتقييد الوصول إلى مجموعة فرعية من التطبيقات، عليك استخدام معرّفاتها الفريدة.
  • request هي الإعدادات التي سيتم استخدامها للشبكة الداخلية. يمكن أن يحتوي ال request على إعدادات جديدة لإعدادات عنوان IP وقدرات الشبكة. إذا تم تسجيل الشبكة في حِزمة الاتصال، سيتم تعديلها وفقًا لملف الإعدادات. لا تبقى هذه الإعدادات محفوظة عند إعادة التشغيل.
  • getMainExecutor() يعرض المُنفِّذ الذي يتم استدعاء المستمع عليه.
  • mCallback هو دالة الاستدعاء المستخدَمة لإعلامك بإكمال العملية، وتعرض عند النجاح اسم الشبكة المعدَّل، أو EthernetNetworkManagementException عند حدوث خطأ.

updateConfiguration() قد تعدّل سمات شبكة يُعتبَر أنّها غير قابلة للتغيير من خلال حِزمة Android Connectivity. يتم إيقاف الشبكة وتعديلها وإعادة تشغيلها لتعديل هذه السمات الثابتة.

تقييد شبكة على مجموعة فرعية من التطبيقات

يمكنك استخدام EthernetManager#updateConfiguration للحد من الوصول إلى مجموعة فرعية فقط من عناوين UID المسموح بها. استخدِم هذه الطريقة لتغطية حالات الاستخدام التي يُشترط فيها ذلك، مثل شبكات المركبات الداخلية التي لا يمكن استخدامها إلا من قِبل مجموعة فرعية صغيرة من تطبيقات المصنّعين الأصليّين للسيارات.

يتتبّع نظام التشغيل 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 لاسترداد 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() الإعدادات لتقييد الشبكة على المجموعة المقدَّمة من أرقام التعريف الفريد للمستخدمين.