安卓14移植以太网&&framework-connectivity-t 编译问题

目录

  • 前言
  • [一、Android14 以太网变更](#一、Android14 以太网变更)
    • [1.1 限制设置有线网参数设置接口方法](#1.1 限制设置有线网参数设置接口方法)
    • [1.2 新增有线网开启关闭接口方法](#1.2 新增有线网开启关闭接口方法)
    • [1.3 新增了 updateConfiguration 接口方法](#1.3 新增了 updateConfiguration 接口方法)
    • [1.4 有线网设置的静态ip和代理信息重启后无效](#1.4 有线网设置的静态ip和代理信息重启后无效)
    • [1.5 EthernetManager相关代码位置移动](#1.5 EthernetManager相关代码位置移动)
      • [1.5.1 你的模块需要引入 libs: ["framework-connectivity.impl"]](#1.5.1 你的模块需要引入 libs: ["framework-connectivity.impl"])
      • [1.5.2 显式添加可见性](#1.5.2 显式添加可见性)
  • 二、移植适配思路

前言

一、Android14 以太网变更

之前只负责过安卓12平台及以下的以太网功能移植(移植到Settings),Android12 到Android 14 网络部分无论是代码存放目录和代码逻辑都是有较多修改的,主要包括以下几个部分。(后续发现部分Android12平台 相对于其他低版本和Android 14也很相似)

1.1 限制设置有线网参数设置接口方法

c 复制代码
packages/modules/Connectivity/framework-t/src/android/net/EthernetManager.java

/**
     * Get Ethernet configuration.
     * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
     * @hide
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public IpConfiguration getConfiguration(String iface) {
        try {
            return mService.getConfiguration(iface);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Set Ethernet configuration.
     * @hide
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
        try {
            mService.setConfiguration(iface, config);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

主要是api加了限制 :maxTargetSdk = Build.VERSION_CODES.R //Android11

所以Android 12 或者更新的版本,在EthernetManager 是调用不到上面几个接口方法的,编译会直接报错:找不到对应的方法!

1.2 新增有线网开启关闭接口方法

c 复制代码
packages\modules\Connectivity\framework-t\src\android\net\EthernetManager.java

    /**
     * Change ethernet setting.
     *
     * @param enabled enable or disable ethernet settings.
     *
     * @hide
     */
    @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 ,之前是要自己实现有线网开关的。需要的权限上面已经说明的,基本是要系统签名的应用才能调用。

1.3 新增了 updateConfiguration 接口方法

c 复制代码
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 request 对象是包含静态ip和代理信息对象和特征属性对象。

后面两个是回调监听,未要求非空,是可以传null 的。

在有线网服务,新api 增加了限制!

c 复制代码
//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, "  updateConfiguration with: iface=" + iface + ", listener=" + listener);
        maybeValidateTestCapabilities(iface, request.getNetworkCapabilities());

        mTracker.updateConfiguration(
                iface, request.getIpConfiguration(), request.getNetworkCapabilities(), listener);
    }

在自己项目中调用此api ,必须设置属性让自己的设备识别为车载项目

或者把车载判断的逻辑去除即可

1.4 有线网设置的静态ip和代理信息重启后无效

c 复制代码
//查看有线网配置信息保存的类:
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();
                }
                // 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, " for read exception:" + e.getMessage());
        }
    }

1.5 EthernetManager相关代码位置移动

从framework移到packages/modules/Connectivity/

(之前目录:frameworks\base\core\java\android\net\EthernetManager.java)

后面开发Android12 或新版本代码,会发现wifi 、蓝牙、热点 之前 framework 的源码都移动到了下面的package目录:

如果你在其他的framework包里调用Connectivity这个 模块里面的内容,大概率是会编译报错的!

你需要添加两处修改:

1.5.1 你的模块需要引入 libs: ["framework-connectivity.impl"]

framework-connectivity 只提供公共的 stub
libs: ["framework-connectivity.impl"]。将完整的实现(包括像 IConnectivityManager 这样的内部/隐藏类)包含在编译时的类路径中。

1.5.2 显式添加可见性

framework-connectivity-t 这个包不是你想用就能用的,需要在 Connectivity下面对应的模块添加你需要引入的模块位置,显式添加可见性

c 复制代码
java_sdk_library {
    name: "framework-connectivity-t",
    defaults: [
        "framework-connectivity-t-defaults",
        "enable-framework-connectivity-t-targets",
    ],
    // Do not add static_libs to this library: put them in framework-connectivity instead.
    // The jarjar rules are only so that references to jarjared utils in
    // framework-connectivity-pre-jarjar match at runtime.
    jarjar_rules: ":framework-connectivity-jarjar-rules",
    stub_only_libs: [
        // Use prebuilt framework-connectivity stubs to avoid circular dependencies
        "sdk_module-lib_current_framework-connectivity",
    ],
    libs: [
        "sdk_module-lib_current_framework-connectivity",
    ],
    permitted_packages: [
        "android.app.usage",
        "android.net",
        "android.net.nsd",
        "android.nearby",
        "com.android.connectivity",
        "com.android.nearby",
    ],

    hidden_api: {
        max_target_o_low_priority: [
            "hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt",
        ],
        max_target_r_low_priority: [
            "hiddenapi/hiddenapi-max-target-r-loprio.txt",
        ],
        unsupported: [
            "hiddenapi/hiddenapi-unsupported-tiramisu.txt",
        ],
    },

    impl_library_visibility: [
+        "//你需要引入的模块位置"
        "//packages/modules/Connectivity/Tethering/apex",
        // In preparation for future move
        "//packages/modules/Connectivity/apex",
        "//packages/modules/Connectivity/service", // For R8 only
        "//packages/modules/Connectivity/service-t",
        "//packages/modules/Connectivity/nearby:__subpackages__",
        "//frameworks/base",

        // Tests using hidden APIs
        "//cts/tests/netlegacy22.api",
        "//cts/tests/tests/app.usage", // NetworkUsageStatsTest
        "//external/sl4a:__subpackages__",
        "//frameworks/base/core/tests/bandwidthtests",
        "//frameworks/base/core/tests/benchmarks",
        "//frameworks/base/core/tests/utillib",
        "//frameworks/base/tests/vcn",
        "//frameworks/libs/net/common/testutils",
        "//frameworks/libs/net/common/tests:__subpackages__",
        "//frameworks/opt/net/ethernet/tests:__subpackages__",
        "//frameworks/opt/telephony/tests/telephonytests",
        "//packages/modules/CaptivePortalLogin/tests",
        "//packages/modules/Connectivity/Tethering/tests:__subpackages__",
        "//packages/modules/Connectivity/tests:__subpackages__",
        "//packages/modules/IPsec/tests/iketests",
        "//packages/modules/NetworkStack/tests:__subpackages__",
        "//packages/modules/Wifi/service/tests/wifitests",
    ],
}

否则会编译报错

c 复制代码
error: frameworks/base/packages/我的模块位置/Android.bp:11:1: module "我的模块" variant "android_common": depends on //packages/modules/Connectivity/framework:framework-connectivity.impl which is not visible to this module
You may need to add "//frameworks/base/packages/我的模块位置" to its visibility
13:54:17 soong bootstrap failed with: exit status 1

二、移植适配思路

主要是从以下两个方面:

(1)使用新api接口设置静态ip和代理信息

(2)移除源码中限制接口的版本号 目前我采用的是一,因为项目需要过gms认证,只能使用一,因为gms合入mainline,packages\modules\Connectivity生成的jar会被覆盖。

使用系统提供的更新ip方法:

c 复制代码
   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);

旧版本的很多接口在新版本是没有的,但是都能被新的接口适配替代!

相关推荐
zhaoyufei1332 小时前
Android13删除Taskbar
android
6***B484 小时前
存储过程(SQL)
android·数据库·sql
学困昇5 小时前
C++中的异常
android·java·c++
Jerry6 小时前
问题记录 - Android IdleHandler 没有执行
android
没有了遇见6 小时前
Android ButterKnife Android 35情况下 适配 Gradle 8.+
android
方白羽6 小时前
Android多层嵌套RecyclerView滚动
android·java·kotlin
菜就多学7 小时前
SurfaceControlViewHost 实现跨进程UI渲染
android·设计
2501_915106328 小时前
iOS App 测试工具全景分析,构建从开发调试到线上监控的多阶段工具链体系
android·测试工具·ios·小程序·uni-app·iphone·webview
小羊在奋斗9 小时前
MySQL表的约束:从基础到核心(附场景+案例)
android·数据库·mysql
e***19359 小时前
MySQL-mysql zip安装包配置教程
android·mysql·adb