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