شبکه های اترنت داخلی را پیکربندی کنید

سیستم عامل اندروید اتو نسخه ۱۳ و بالاتر شامل ویژگی‌هایی است که به شما امکان پیکربندی و مدیریت شبکه‌های اترنت را می‌دهد. شکل ۱ یک نمودار شبکه نمونه برای یک خودرو را نشان می‌دهد:

شبکه اندروید اتو

شکل 1. شبکه اندروید اتو.

این شکل، متدهای فراخوانی برنامه شبکه 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_ethernet_interfaces را از config.xml نشان می‌دهد.

نکات کلیدی در مورد کد

  • eth1 ، eth2 و eth3 نام‌های رابط شبکه‌ای هستند که پیکربندی می‌شوند.
  • اعداد متوالی 12, 13, 14, 15 نشان دهنده فعال بودن قابلیت‌های شبکه هستند.
  • ip= ، gateway= و dns برای تنظیم آدرس 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() را برای تبدیل نام‌های بسته قابل خواندن توسط انسان به شناسه منحصر به فرد لینوکس (UID) فراخوانی می‌کند. معمولاً شما UIDهای بسته‌های مرتبط با آنها را از قبل نمی‌دانید. بنابراین، اگر می‌خواهید از EthernetManager.updateConfiguration() برای محدود کردن دسترسی به زیرمجموعه‌ای از برنامه‌ها استفاده کنید، باید از UIDهای آنها استفاده کنید.
  • request ، پیکربندی مورد استفاده برای شبکه داخلی است. این درخواست می‌تواند شامل تنظیمات جدیدی برای پیکربندی IP و قابلیت‌های شبکه باشد. اگر شبکه در پشته اتصال ثبت شده باشد، طبق پیکربندی به‌روزرسانی می‌شود. این پیکربندی در راه‌اندازی‌های مجدد باقی نمی‌ماند.
  • getMainExecutor() اجراکننده‌ای را برمی‌گرداند که شنونده (listener) روی آن فراخوانی شده است.
  • mCallback یک فراخوانی برگشتی است که برای اعلام تکمیل عملیات استفاده می‌شود و در صورت موفقیت، نام شبکه به‌روزرسانی‌شده یا در صورت خطا، EthernetNetworkManagementException برمی‌گرداند.

updateConfiguration() ممکن است ویژگی‌های شبکه‌ای را که توسط پشته اتصال اندروید تغییرناپذیر در نظر گرفته می‌شود، به‌روزرسانی کند. شبکه برای به‌روزرسانی این ویژگی‌های تغییرناپذیر، از دسترس خارج، به‌روزرسانی و دوباره فعال می‌شود.

محدود کردن یک شبکه به زیرمجموعه‌ای از برنامه‌ها

شما می‌توانید از EthernetManager#updateConfiguration برای محدود کردن دسترسی فقط به زیرمجموعه‌ای از شناسه‌های کاربری مجاز استفاده کنید. از این روش برای پوشش مواردی استفاده کنید که این مورد مورد نیاز است، مانند شبکه‌های داخلی وسایل نقلیه که فقط توسط زیرمجموعه کوچکی از برنامه‌های OEM قابل استفاده هستند.

اندروید در درجه اول برنامه‌ها را بر اساس 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 مجموعه‌ای از شناسه‌های کاربری (UID) برنامه است که اجازه استفاده از شبکه را دارند.
  • updateConfiguration() پیکربندی را به‌روزرسانی می‌کند تا شبکه را به مجموعه UIDهای ارائه شده محدود کند.