מערכת ההפעלה Android Auto מגרסה 13 ומעלה כוללת תכונות שמאפשרות להגדיר ולנהל רשתות Ethernet. איור 1 מציג תרשים רשת לדוגמה של מכונית:
איור 1. רשתות ב-Android Auto.
באיור הזה מוצגות שיטות להפעלת אפליקציית רשת של יצרן ציוד מקורי (OEM) במחלקה EthernetManager כדי להגדיר ולנהל רשתות Ethernet מובנות (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.xml.config_ethernet_interfaces
מידע חשוב על הקוד
-
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.
עדכון הגדרת הרשת
כדי לעדכן את ההגדרות של רשת 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. בדרך כלל, אתם לא יודעים מראש את מזהי ה-UID של החבילות המשויכות. לכן, אם רוצים להשתמש ב-EthernetManager.updateConfiguration()כדי להגביל את הגישה לקבוצת משנה של אפליקציות, צריך להשתמש במזהי ה-UID שלהן. -
requestהיא ההגדרה שתשמש לרשת הפנימית. הבקשה יכולה להכיל הגדרות חדשות להגדרת כתובת ה-IP וליכולות הרשת. אם הרשת רשומה במערך הקישוריות, היא מתעדכנת בהתאם להגדרה. ההגדרה הזו לא נשמרת אחרי הפעלה מחדש. -
getMainExecutor()מחזירה את ה-executor שבו מופעל ה-listener. -
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 שצוינה.