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

سیستم عامل Android Auto نسخه 13 و بالاتر دارای ویژگی هایی است که به شما امکان می دهد شبکه های اترنت را پیکربندی و مدیریت کنید. شکل 1 نمونه ای از نمودار شبکه را برای یک خودرو نشان می دهد:

شبکه Android Auto

شکل 1. شبکه 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_ethernet_interfaces را از config.xml نشان می دهد.

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

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

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

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

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

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