מערכת ההפעלה של 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_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
או בתצורת ברירת המחדל של רשת ה-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
הוא קריאה חוזרת (callback) שמשמשת להודעה על השלמה, ומחזירה את שם הרשת המעודכן אם הפעולה בוצעה בהצלחה, או את הערך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 וליכולות הרשת. אם הרשת רשומה ב-Connectivity Stack, היא מתעדכנת בהתאם להגדרה. ההגדרה הזו לא נשמרת אחרי הפעלה מחדש.- הפונקציה
getMainExecutor()
מחזירה את המאגר שבו מתבצע ההפעלה של המאזין. mCallback
הוא פונקציית ה-callback שמשמשת להודעה על השלמה, ומחזירה את שם הרשת המעודכן אם הפעולה בוצעה בהצלחה, או את הערךEthernetNetworkManagementException
אם הייתה שגיאה.
updateConfiguration()
עשוי לעדכן מאפיינים של רשת שנחשבת לבלתי ניתנת לשינוי על ידי סטאק הקישוריות של Android. כדי לעדכן את המאפיינים הבלתי משתנים האלה, צריך להשבית את הרשת, לעדכן אותה ולהפעיל אותה מחדש.
הגבלת רשת לקבוצת משנה של אפליקציות
אפשר להשתמש ב-EthernetManager#updateConfiguration
כדי להגביל את הגישה רק לקבוצת משנה של מזהי UID מותרים. מומלץ להשתמש בשיטה הזו בתרחישי שימוש שבהם היא נדרשת, למשל ברשתות פנימיות של כלי רכב שרק קבוצת משנה קטנה של אפליקציות של יצרני ציוד מקורי יכולה להשתמש בהן.
מערכת 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 שצוינה.