Android 13 有线以太网静态ip保存逻辑梳理分析

源码环境:高通Android 13

这里特别说明,Android13中,ipconfig.txt配置文件目录有改变

以前:/data/misc/ethernet/ipconfig.txt

最新的有线网配置文件保存目录:

/data/misc/apexdata/com.android.tethering/misc/ethernet/ipconfig.txt

一、Android 版本影响

首先就是Android 11 与 12 的有线网络版本差距还是比较大的,源码目录也变了,之前目录frameworks/opt/net/ethernet/java/com/android/server/ethernet ,现在改成了packages/modules/Connectivity/service-t/src/com/android/server/ethernet,所以如果之前只在11上面适配过,那么对于12来说,适配还是需要花费一点功夫,具体的差异在之后的部分会记录,但是12与13的有线网络差异就较小了,并且看起来,13的以太网接口以及逻辑比12来说更为完善。

二、配置以太网所需要的类

配置以太网所需要的java类大概有以下几个,其实这几个类从Android9开始就是以太网配置的主要java类了

(1)、frameworks/base/core/java/android/net/EthernetManager.java

EthernetManager.java此是上层管理以太网的类,我们常通过context.getSystemService(Context.ETHERNET_SERVICE)获得他的实例对象

(2)、packages/modules/Connectivity/framework/src/android/net/IpConfiguration.java

这个类主要就是用来配置IP状态的,包括动态和静态

(3)、packages/modules/Connectivity/framework/src/android/net/StaticIpConfiguration.java

这个类主要就是用来配置静态IP的,这个类之前也是在frameworks/base/core/java/android/net/路径下,12里面也移到了packages/modules/Connectivity/framework/src/android/net/下

三、有线以太网静态ip保存逻辑从源码逐步分析

java 复制代码
1、packages/modules/Connectivity/framework-t/src/android/net/EthernetManager.java 
 public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
        try {
            mService.setConfiguration(iface, config);//这里调用的是EthernetServiceImpl.java中的setConfiguration
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }



2、packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
  /**
     * Set Ethernet configuration
     */
    @Override
    public void setConfiguration(String iface, IpConfiguration config) {
        throwIfEthernetNotStarted();

        PermissionUtils.enforceNetworkStackPermission(mContext);
        if (mTracker.isRestrictedInterface(iface)) {
            PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG);
        }

        // TODO: this does not check proxy settings, gateways, etc.
        // Fix this by making IpConfiguration a complete representation of static configuration.
        mTracker.updateIpConfiguration(iface, new IpConfiguration(config));//这里更新保存
    }


3、packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetTracker.java
EthernetTracker中主要做了以下两件事 :
(1). 首先更新 ip config的,这个和静态ip相关;
(2). 根据iface,调用addInterface创建interface

   void updateIpConfiguration(String iface, IpConfiguration ipConfiguration) {
        if (DBG) {
            Log.i(TAG, "updateIpConfiguration, iface: " + iface + ", cfg: " + ipConfiguration);
        }
        writeIpConfiguration(iface, ipConfiguration);
        mHandler.post(() -> {
            mFactory.updateInterface(iface, ipConfiguration, null, null);
            broadcastInterfaceStateChange(iface);
        });
    }


   private void writeIpConfiguration(@NonNull final String iface,
            @NonNull final IpConfiguration ipConfig) {
        mConfigStore.write(iface, ipConfig);//这里调用了EthernetConfigStore.java中的write
        mIpConfigurations.put(iface, ipConfig);
    }


4、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 APEX_IP_CONFIG_FILE_PATH = ApexEnvironment.getApexEnvironment(
            TETHERING_MODULE_NAME).getDeviceProtectedDataDir() + FILE_PATH;


 public void write(String iface, IpConfiguration config) {
        write(iface, config, APEX_IP_CONFIG_FILE_PATH + CONFIG_FILE);//注意:这里Android13调整了保存路径,全路径:/data/misc/apexdata/com.android.tethering/misc/ethernet/ipconfig.txt
        //Android 10版本保存路径为:/data/misc/ethernet/ipconfig.txt
    }



 void write(String iface, IpConfiguration config, String filepath) {
        boolean modified;

        synchronized (mSync) {
            if (config == null) {
                modified = mIpConfigurations.remove(iface) != null;
            } else {
                IpConfiguration oldConfig = mIpConfigurations.put(iface, config);
                modified = !config.equals(oldConfig);
            }

            if (modified) {
                mStore.writeIpConfigurations(filepath, mIpConfigurations);//这里调用的是IpConfigStore.java
            }
        }
    }



5、packages/modules/Connectivity/service-t/src/com/android/server/net/IpConfigStore.java
 /**
     *  Write the IP configuration associated to the target networks to the destination path.
     */
    public void writeIpConfigurations(String filePath,
                                      ArrayMap<String, IpConfiguration> networks) {
        mWriter.write(filePath, out -> {
            out.writeInt(IPCONFIG_FILE_VERSION);
            for (int i = 0; i < networks.size(); i++) {
                writeConfig(out, networks.keyAt(i), networks.valueAt(i));
            }
        });
    }



  private static boolean writeConfig(DataOutputStream out, String configKey,
            IpConfiguration config) throws IOException {
        return writeConfig(out, configKey, config, IPCONFIG_FILE_VERSION);
    }



//这里最终完成静态ip写到配置文件:/data/misc/apexdata/com.android.tethering/misc/ethernet/ipconfig.txt
  public static boolean writeConfig(DataOutputStream out, String configKey,
                                IpConfiguration config, int version) throws IOException {
        boolean written = false;

        try {
            switch (config.getIpAssignment()) {
                case STATIC:
                    out.writeUTF(IP_ASSIGNMENT_KEY);
                    out.writeUTF(config.getIpAssignment().toString());
                    StaticIpConfiguration staticIpConfiguration = config.getStaticIpConfiguration();
                    if (staticIpConfiguration != null) {
                        if (staticIpConfiguration.getIpAddress() != null) {
                            LinkAddress ipAddress = staticIpConfiguration.getIpAddress();
                            out.writeUTF(LINK_ADDRESS_KEY);
                            out.writeUTF(ipAddress.getAddress().getHostAddress());
                            out.writeInt(ipAddress.getPrefixLength());
                        }
                        if (staticIpConfiguration.getGateway() != null) {
                            out.writeUTF(GATEWAY_KEY);
                            out.writeInt(0);  // Default route.
                            out.writeInt(1);  // Have a gateway.
                            out.writeUTF(staticIpConfiguration.getGateway().getHostAddress());
                        }
                        for (InetAddress inetAddr : staticIpConfiguration.getDnsServers()) {
                            out.writeUTF(DNS_KEY);
                            out.writeUTF(inetAddr.getHostAddress());
                        }
                    }
                    written = true;
                    break;
                case DHCP:
                    out.writeUTF(IP_ASSIGNMENT_KEY);
                    out.writeUTF(config.getIpAssignment().toString());
                    written = true;
                    break;
                case UNASSIGNED:
                /* Ignore */
                    break;
                default:
                    loge("Ignore invalid ip assignment while writing");
                    break;
            }

            switch (config.getProxySettings()) {
                case STATIC:
                    ProxyInfo proxyProperties = config.getHttpProxy();
                    String exclusionList = ProxyUtils.exclusionListAsString(
                            proxyProperties.getExclusionList());
                    out.writeUTF(PROXY_SETTINGS_KEY);
                    out.writeUTF(config.getProxySettings().toString());
                    out.writeUTF(PROXY_HOST_KEY);
                    out.writeUTF(proxyProperties.getHost());
                    out.writeUTF(PROXY_PORT_KEY);
                    out.writeInt(proxyProperties.getPort());
                    if (exclusionList != null) {
                        out.writeUTF(EXCLUSION_LIST_KEY);
                        out.writeUTF(exclusionList);
                    }
                    written = true;
                    break;
                case PAC:
                    ProxyInfo proxyPacProperties = config.getHttpProxy();
                    out.writeUTF(PROXY_SETTINGS_KEY);
                    out.writeUTF(config.getProxySettings().toString());
                    out.writeUTF(PROXY_PAC_FILE);
                    out.writeUTF(proxyPacProperties.getPacFileUrl().toString());
                    written = true;
                    break;
                case NONE:
                    out.writeUTF(PROXY_SETTINGS_KEY);
                    out.writeUTF(config.getProxySettings().toString());
                    written = true;
                    break;
                case UNASSIGNED:
                    /* Ignore */
                    break;
                default:
                    loge("Ignore invalid proxy settings while writing");
                    break;
            }

            if (written) {
                out.writeUTF(ID_KEY);
                if (version < 3) {
                    out.writeInt(Integer.valueOf(configKey));
                } else {
                    out.writeUTF(configKey);
                }
            }
        } catch (NullPointerException e) {
            loge("Failure in writing " + config + e);
        }
        out.writeUTF(EOS);

        return written;
    }
相关推荐
千里马学框架5 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台5 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone5 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc5 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077005 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui