Android13の有線変更点
Android12、13のネットワーク部分ではイーサネット関連の機能はあまり変わっていません。 Android11からAndroid 12では、ネットワーク部分はコード格納ディレクトリとコードロジックの両方で大きく変更されており、主に以下の部分が含まれます。
-
有線ネットワークパラメータを設定するためのインターフェース方法は制限されています。
-
有線ネットワークインターフェイスを開閉する方法を追加しました
-
updateConfiguration インターフェイス メソッドを追加しました
-
再起動後、有線ネットワークで設定した固定IPおよびプロキシ情報が無効になる
-
EthernetManager 関連のコードは、フレームワークから package/modules/Connectivity/ (前のディレクトリ: Frameworks\base\core\java\android\net\EthernetManager.java) に移動されました。Android12 または新しいバージョンのコードを開発すると、次のことがわかります。 Wi-Fi、Bluetooth、およびホットスポットは以前です。 フレームワークのソース コードは、次のパッケージ ディレクトリに移動されました。
上記の変更を踏まえて。アプリ API (targetSdkVersion) が Android12 に設定されている場合、アプリは以前のインターフェイスを使用して有線ネットワーク情報を設定できません。
-
有線ネットワークパラメータを設定するためのインターフェース方法は制限されています。
//packages\modules\Connectivity\framework-t\src\android\net\EthernetManager.java
/**
* Get Ethernet configuration.
* @return the Ethernet Configuration, contained in {@link IpConfiguration}.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
public @NonNull IpConfiguration getConfiguration(@NonNull String iface) {
try {
return mService.getConfiguration(iface);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Set Ethernet configuration.
* @hide
*/
@SystemApi(client = MODULE_LIBRARIES)
public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
try {
mService.setConfiguration(iface, config);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public String[] getAvailableInterfaces() {
try {
return mService.getAvailableInterfaces();
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
上記の観点から見ると、主な理由は、API に制限が追加されたことです。 maxTargetSdk = Build.VERSION_CODES.R //Android11
したがって、Android 12 以降のバージョンでは、EthernetManager で上記のインターフェイス メソッドを呼び出すことができません。
-
有線ネットワークインターフェイスを開閉する方法を追加しました
//packages\modules\Connectivity\framework-t\src\android\net\EthernetManager.java
@RequiresPermission(anyOf = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
android.Manifest.permission.NETWORK_STACK,
android.Manifest.permission.NETWORK_SETTINGS})
@SystemApi(client = MODULE_LIBRARIES)
public void setEthernetEnabled(boolean enabled) {
try {
mService.setEthernetEnabled(enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
これは新しいインターフェイス メソッド setEthernetEnabled です。以前は、有線ネットワーク スイッチを自分で実装する必要がありました。必要な権限については上で説明しましたが、基本的に、アプリケーションは呼び出す前にシステムによって署名される必要があります。
-
updateConfiguration インターフェイス メソッドを追加しました
//packages\modules\Connectivity\framework-t\src\android\net\EthernetManager.java
@SystemApi
@RequiresPermission(anyOf = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
android.Manifest.permission.NETWORK_STACK,
android.Manifest.permission.MANAGE_ETHERNET_NETWORKS})
public void updateConfiguration(
@NonNull String iface,
@NonNull EthernetNetworkUpdateRequest request,
@Nullable @CallbackExecutor Executor executor,
@Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
Objects.requireNonNull(iface, "iface must be non-null");
Objects.requireNonNull(request, "request must be non-null");
final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver(
executor, callback);
try {
mService.updateConfiguration(iface, request, proxy);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
String iface //ノード名: eth0 / eth1
EthernetNetworkUpdateRequest リクエスト オブジェクトには、静的 IPおよびプロキシ情報オブジェクトと特性属性オブジェクトが含まれます。
後の 2 つはコールバック モニターであり、null 以外である必要はなく、null を渡すことができます。
さらに、ケーブル ネットワーク サービスでは、新しい API により制限が追加されました。
//packages\modules\Connectivity\service-t\src\com\android\server\ethernet\EthernetServiceImpl.java
@Override
public void updateConfiguration(@NonNull final String iface,
@NonNull final EthernetNetworkUpdateRequest request,
@Nullable final INetworkInterfaceOutcomeReceiver listener) {
Objects.requireNonNull(iface);
Objects.requireNonNull(request);
throwIfEthernetNotStarted();
// TODO: validate that iface is listed in overlay config_ethernet_interfaces
// only automotive devices are allowed to set the NetworkCapabilities using this API
//only automotive devices 表明,只有 车载设备支持设置该方法
+ // 非车载项目必须注释调方法:enforceAdminPermission ,否则会报错,这里是校验是否是车载项目
+ //enforceAdminPermission(iface, request.getNetworkCapabilities() != null,
+ // "updateConfiguration() with non-null capabilities");
+ Log.i(TAG, " lwz add updateConfiguration with: iface=" + iface + ", listener=" + listener);
maybeValidateTestCapabilities(iface, request.getNetworkCapabilities());
mTracker.updateConfiguration(
iface, request.getIpConfiguration(), request.getNetworkCapabilities(), listener);
}
したがって、独自のプロジェクトで新しい API を呼び出す場合は、車載プロジェクトとして認識されるようにプロパティを設定するか、車載判定のロジックを削除する必要があります。
-
再起動後、有線ネットワークで設定した固定IPおよびプロキシ情報が無効になる
//查看有线网配置信息保存的类:
packages\modules\Connectivity\service-t\src\com\android\server\ethernet\EthernetConfigStore.java
private static final String CONFIG_FILE = "ipconfig.txt";
private static final String FILE_PATH = "/misc/ethernet/";
private static final String LEGACY_IP_CONFIG_FILE_PATH = Environment.getDataDirectory() + FILE_PATH;
//Android13 新增下面路径:
private static final String APEX_IP_CONFIG_FILE_PATH = ApexEnvironment.getApexEnvironment(
TETHERING_MODULE_NAME).getDeviceProtectedDataDir() + FILE_PATH; // TETHERING_MODULE_NAME --》com.android.tethering
/**
可以看到之前的路径是:
/data/misc/ethernet/ipconfig.txt
最新的有线网配置文件保存目录:
/data/misc/apexdata/com.android.tethering/misc/ethernet/ipconfig.txt
可能存在因为未成功保存本地配置文件,所以每次开机重启后,无法读取到静态ip和代理等信息。
所以出现 有线网设置的静态ip和代理信息重启后无效 问题。主要原因为开机读取的时候,目录未成功创建,故保存未成功。
可以参考如下:
*/
//packages\modules\Connectivity/service-t/src/com/android/server/ethernet/EthernetConfigStore.java
@VisibleForTesting
void read(final String newFilePath, final String oldFilePath, final String filename) {
try {
synchronized (mSync) {
// Attempt to read the IP configuration from apex file path first.
if (doesConfigFileExist(newFilePath + filename)) {
loadConfigFileLocked(newFilePath + filename);
return;
}
//ik-phoebe add for create dir data/misc/apexdata/com.android.tethering/misc/ethernet
final File directory = new File(newFilePath);
if (!directory.exists()) {
boolean mkdirs = directory.mkdirs();
Log.d(TAG, "zmm add for mkdirs:" + newFilePath + ",result:" + mkdirs);
}
// If the config file doesn't exist in the apex file path, attempt to read it from
// the legacy file path, if config file exists, write the legacy IP configuration to
// apex config file path, this should just happen on the first boot. New or updated
// config entries are only written to the apex config file later.
if (!doesConfigFileExist(oldFilePath + filename)) return;
loadConfigFileLocked(oldFilePath + filename);
writeLegacyIpConfigToApexPath(newFilePath, oldFilePath, filename);
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "zmm add for read exception:" + e.getMessage());
}
}
Android13 有線ネットワーク適応のアイデア
主に次の 2 つの側面からです。
(1) 新しいAPIインターフェースを使用して静的IPおよびプロキシ情報を設定します
(2) ソース コード内の制限されたインターフェイスのバージョン番号を削除します。現在は 2 つを使用していますが、プロジェクトに gms 認証が必要な場合は、メインラインのパッケージ\モジュールにマージされるときに gms によって生成される jar が使用できるため、使用できるのは 1 つだけです。 \接続は上書きされます。
diff --git a/framework-t/api/module-lib-current.txt b/framework-t/api/module-lib-current.txt
index 5a8d47b..177f6c5 100644
--- a/framework-t/api/module-lib-current.txt
+++ b/framework-t/api/module-lib-current.txt
@@ -44,9 +44,11 @@ package android.net {
public class EthernetManager {
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addEthernetStateListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addInterfaceStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.InterfaceStateListener);
+ method @NonNull public android.net.IpConfiguration getConfiguration(@NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public java.util.List<java.lang.String> getInterfaceList();
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void removeEthernetStateListener(@NonNull java.util.function.IntConsumer);
method public void removeInterfaceStateListener(@NonNull android.net.EthernetManager.InterfaceStateListener);
+ method public void setConfiguration(@NonNull String, @NonNull android.net.IpConfiguration);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setEthernetEnabled(boolean);
method public void setIncludeTestInterfaces(boolean);
field public static final int ETHERNET_STATE_DISABLED = 0; // 0x0
diff --git a/framework-t/src/android/net/EthernetManager.java b/framework-t/src/android/net/EthernetManager.java
index 886d194..9c675fb 100644
--- a/framework-t/src/android/net/EthernetManager.java
+++ b/framework-t/src/android/net/EthernetManager.java
@@ -191,8 +191,8 @@ public class EthernetManager {
* @return the Ethernet Configuration, contained in {@link IpConfiguration}.
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public IpConfiguration getConfiguration(String iface) {
+ @SystemApi(client = MODULE_LIBRARIES)
+ public @NonNull IpConfiguration getConfiguration(@NonNull String iface) {
try {
return mService.getConfiguration(iface);
} catch (RemoteException e) {
@@ -204,7 +204,7 @@ public class EthernetManager {
* Set Ethernet configuration.
* @hide
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @SystemApi(client = MODULE_LIBRARIES)
public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
try {
mService.setConfiguration(iface, config);
--
2.17.1
もちろん、最善の方法は、システムが提供する IP 更新メソッドを使用することです。
IpConfiguration.Builder build = new IpConfiguration.Builder();
EthernetNetworkUpdateRequest.Builder requestBuilder = new EthernetNetworkUpdateRequest.Builder();
build.setHttpProxy(proxyinfo);
//如果是静态ip,需要创建对应的静态staticIpConfiguration
build.setStaticIpConfiguration(staticIpConfiguration);
requestBuilder.setIpConfiguration(build.build());
mEthManager.updateConfiguration("eth0", requestBuilder.build(), null, null);
以上はAndroid13 Ethernet関連のアップデートです。
シングルサイクル「大慈悲マントラ」