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

يتضمّن نظام التشغيل Android Auto الإصدار 13 والإصدارات الأحدث ميزات تتيح لك ضبط شبكات Ethernet وإدارتها. يعرض الشكل 1 مثالاً على رسم بياني لشبكة سيارة:

الشبكات في Android Auto

الشكل 1. شبكة Android Auto

يوضّح هذا الشكل طرق استدعاء تطبيق الشبكات الخاص بمصنّع المعدات الأصلية في الفئة EthernetManager لضبط شبكات إيثرنت المدمجة وإدارتها (eth0.1 وeth0.2 وeth0.3). لا يتناول هذا المستند بقية الشكل 1.

ضبط إعدادات شبكة Ethernet التلقائية

لضبط إعدادات الشبكة التلقائية، استخدِم تراكب الموارد 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 عند حدوث خطأ.

تعديل إعدادات الشبكة

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

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

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

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

يتتبّع نظام التشغيل Android التطبيقات بشكل أساسي من خلال معرّف المستخدم (UID). يوضّح الرمز التالي من UIDToPackageNameConverter.java كيفية الحصول على سلسلة من معرّفات UID من سلسلة من أسماء الحِزم:

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 كيفية تعديل إعدادات واجهة الشبكة باستخدام معرّفات UID للتطبيقات المسموح لها باستخدام الشبكة:

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

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

  • allowUids هي مجموعة أرقام التعريف الفريدة للتطبيقات المسموح لها باستخدام الشبكة.
  • تعدّل updateConfiguration() الإعدادات لحصر الشبكة على مجموعة أرقام التعريف الفريدة (UID) المقدَّمة.