Android13 原生以太网实现设置静态IP

2 篇文章 0 订阅
1 篇文章 0 订阅

一、引言


        首先需要实现android13设置静态IP的功能,就要对android13以太网架构变化大致理解,谷歌把以太网相关的功能进行模块化,提取到packages/modules/Connectivity/目录,导致之前的实现需要调整,本文主要从2大块进行阐述,分别为framework与原生Settings。

        本文涉及功能点主要有如下几点:

        1.设置IP的方式分为DHCP和静态两种

        2.IP地址的设置

        3.子网掩码设置

        4.DNS设置

        5.网关设置

        6.代理设置

二、Framework部分

        2.1、涉及修改的类

packages/modules/Connectivity/framework-t/api/module-lib-current.txt
packages/modules/Connectivity/framework-t/src/android/net/EthernetManager.java
packages/modules/Connectivity/framework-t/src/android/net/IEthernetManager.aidl
packages/modules/Connectivity/framework/api/current.txt
packages/modules/Connectivity/framework/api/system-current.txt
packages/modules/Connectivity/framework/src/android/net/IpConfiguration.java
packages/modules/Connectivity/framework/src/android/net/ProxyInfo.java
packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetTracker.java

        2.2、涉及类修改阐述

                android其实不管怎么更新,都离不开client-aidl-server这样的模式,所以大体思路就是根

                据以太网源码框架,在其上模仿原有的接口进行添加内容的方式,先把路打通。

                2.2.1、客户端接口添加及修改

1.IEthernetManager.aidl类中添加4个接口,提供给上层使用

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net;

import android.net.IpConfiguration;
import android.net.IEthernetServiceListener;
import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkUpdateRequest;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.ITetheredInterfaceCallback;

import java.util.List;

/**
 * Interface that answers queries about, and allows changing
 * ethernet configuration.
 */
/** {@hide} */
interface IEthernetManager
{
    String[] getAvailableInterfaces();
    IpConfiguration getConfiguration(String iface);
    void setConfiguration(String iface, in IpConfiguration config);
    boolean isAvailable(String iface);
    void addListener(in IEthernetServiceListener listener);
    void removeListener(in IEthernetServiceListener listener);
    void setIncludeTestInterfaces(boolean include);
    void requestTetheredInterface(in ITetheredInterfaceCallback callback);
    void releaseTetheredInterface(in ITetheredInterfaceCallback callback);
    void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request,
        in INetworkInterfaceOutcomeReceiver listener);
    void connectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
    void disconnectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener);
    void setEthernetEnabled(boolean enabled);
    List<String> getInterfaceList();

    //added by cgt Adding an Ethernet Interface start
    String getIpAddress(String iface);
    String getNetmask(String iface);
    String getGateway(String iface);
    String getDns(String iface);
    //added by cgt Adding an Ethernet Interface end

}

2.EthernetManager.java类中实现aidl中的4个接口,并修改android13 APP调用以太网API时受限制

 import java.util.Objects;
 import java.util.concurrent.Executor;
 import java.util.function.IntConsumer;
+//added by cgt Adding an Ethernet Interface start
+import java.net.InetAddress;
+import android.net.NetworkUtils;
+//added by cgt Adding an Ethernet Interface end
 
 /**
  * A class that manages and configures Ethernet interfaces.
@@ -191,8 +195,15 @@ 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) {
+    //added by cgt Adding an Ethernet Interface start
+    /*@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public IpConfiguration getConfiguration(String iface) {*/
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    public IpConfiguration getConfiguration(@NonNull String iface) {
+    //added by cgt Adding an Ethernet Interface end
         try {
             return mService.getConfiguration(iface);
         } catch (RemoteException e) {
@@ -204,7 +215,13 @@ public class EthernetManager {
      * Set Ethernet configuration.
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    //added by cgt Adding an Ethernet Interface start
+    //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    //added by cgt Adding an Ethernet Interface end
     public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) {
         try {
             mService.setConfiguration(iface, config);
@@ -217,7 +234,10 @@ public class EthernetManager {
      * Indicates whether the system currently has one or more Ethernet interfaces.
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    //added by cgt Adding an Ethernet Interface start
+    //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage
+    //modified by cengt,ethernet,Adding an Ethernet Interface,20230628-end
     public boolean isAvailable() {
         return getAvailableInterfaces().length > 0;
     }
@@ -228,7 +248,10 @@ public class EthernetManager {
      * @param iface Ethernet interface name
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    //added by cgt Adding an Ethernet Interface start
+    //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage
+    //added by cgt Adding an Ethernet Interface end
     public boolean isAvailable(String iface) {
         try {
             return mService.isAvailable(iface);
@@ -318,7 +341,13 @@ public class EthernetManager {
      * Returns an array of available Ethernet interface names.
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    //added by cgt Adding an Ethernet Interface start
+    //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    //added by cgt Adding an Ethernet Interface end
     public String[] getAvailableInterfaces() {
         try {
             return mService.getAvailableInterfaces();
@@ -696,9 +725,12 @@ public class EthernetManager {
      * is available or not currently.
      * @hide
      */
+    //added by cgt Adding an Ethernet Interface start
+    //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     @SystemApi(client = MODULE_LIBRARIES)
     @NonNull
+    //added by cgt Adding an Ethernet Interface end
     public List<String> getInterfaceList() {
         try {
             return mService.getInterfaceList();
@@ -706,4 +738,78 @@ public class EthernetManager {
             throw e.rethrowAsRuntimeException();
         }
     }
+
+    //added by cgt Adding an Ethernet Interface start
+    /**
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    public String getIpAddress(@NonNull String iface) {
+        try {
+            return mService.getIpAddress(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    public String getNetmask(@NonNull String iface) {
+        try {
+            return mService.getNetmask(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    public String getGateway(@NonNull String iface) {
+        try {
+            return mService.getGateway(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    public String getDns(@NonNull String iface) {
+        try {
+            return mService.getDns(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    @NonNull
+    @UnsupportedAppUsage
+    public static InetAddress iminNumericToInetAddress(@NonNull String text) {
+        return NetworkUtils.numericToInetAddress(text);
+    }
+    //added by cgt Adding an Ethernet Interface end
+
 }

3.module-lib-current.txt类中实现aidl添加接口后系统编译的文件,此文件也可以自行使用make update-api编译生成,如不想编译直接自己实现

+++ b/XXX/packages/modules/Connectivity/framework-t/api/module-lib-current.txt
@@ -44,9 +44,17 @@ 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 @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String[] getAvailableInterfaces();
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.IpConfiguration getConfiguration(@NonNull String);
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getDns(@NonNull String);
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getGateway(@NonNull String);
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public java.util.List<java.lang.String> getInterfaceList();
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getIpAddress(@NonNull String);
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public String getNetmask(@NonNull String);
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static java.net.InetAddress iminNumericToInetAddress(@NonNull String);
     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 @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void setConfiguration(@NonNull String, @No
nNull 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

4.current.txt类中添加ProxyInfo两个构造函数

+++ b/XXX/packages/modules/Connectivity/framework/api/current.txt
@@ -445,6 +445,8 @@ package android.net {
   }
 
   public class ProxyInfo implements android.os.Parcelable {
+    ctor public ProxyInfo(@NonNull String, int, @NonNull String);
+    ctor public ProxyInfo(@NonNull android.net.Uri);
     ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
     method public static android.net.ProxyInfo buildDirectProxy(String, int);
     method public static android.net.ProxyInfo buildDirectProxy(String, int, java.util.List<java.lang.String>);

5.system-current.txt类中添加两个函数

+++ b/xxx/packages/modules/Connectivity/framework/api/system-current.txt
@@ -126,6 +126,7 @@ package android.net {
 
   public final class IpConfiguration implements android.os.Parcelable {
     ctor public IpConfiguration();
+    ctor public IpConfiguration(@NonNull android.net.IpConfiguration.IpAssignment, @NonNull android.net.IpConfiguration.ProxySettings, @NonNull android.net.StaticIpConfiguration, @NonNull android.net.ProxyInfo);
     ctor public IpConfiguration(@NonNull android.net.IpConfiguration);
     method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment();
     method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();

6.IpConfiguration.java类中修改android13 APP调用以太网API时受限制

+++ b/xxx/packages/modules/Connectivity/framework/src/android/net/IpConfiguration.java
@@ -103,11 +103,14 @@ public final class IpConfiguration implements Parcelable {
     }
 
     /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public IpConfiguration(IpAssignment ipAssignment,
-                           ProxySettings proxySettings,
-                           StaticIpConfiguration staticIpConfiguration,
-                           ProxyInfo httpProxy) {
+    //added by cgt Adding an Ethernet Interface start
+    //@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @SystemApi
+    //added by cgt Adding an Ethernet Interface end
+    public IpConfiguration(@NonNull IpAssignment ipAssignment,
+                           @NonNull ProxySettings proxySettings,
+                           @NonNull StaticIpConfiguration staticIpConfiguration,
+                           @NonNull ProxyInfo httpProxy) {
         init(ipAssignment, proxySettings, staticIpConfiguration, httpProxy);
     }
 

7.ProxyInfo.java类中修改android13 APP调用以太网API时受限制

+++ b/xxx/packages/modules/Connectivity/framework/src/android/net/ProxyInfo.java
@@ -103,10 +103,11 @@ public class ProxyInfo implements Parcelable {
 
     /**
      * Create a ProxyProperties that points at a HTTP Proxy.
-     * @hide
      */
-    @UnsupportedAppUsage
-    public ProxyInfo(String host, int port, String exclList) {
+    //added by cgt Adding an Ethernet Interface start
+    //@UnsupportedAppUsage
+    //added by cgt Adding an Ethernet Interface end
+    public ProxyInfo(@NonNull String host, int port, @NonNull String exclList) {
         mHost = host;
         mPort = port;
         mExclusionList = exclList;
@@ -116,7 +117,6 @@ public class ProxyInfo implements Parcelable {
 
     /**
      * Create a ProxyProperties that points at a PAC URL.
-     * @hide
      */
     public ProxyInfo(@NonNull Uri pacFileUrl) {
         mHost = LOCAL_HOST;
                2.2.2、客户端接口添加及修改

1.EthernetNetworkFactory.java类中实现4个接口

+++ b/xxx/packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -58,6 +58,17 @@ import java.io.FileDescriptor;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+//added by cgt Adding an Ethernet Interface start
+import android.net.EthernetManager;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.RouteInfo;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.RouteInfo;
+//added by cgt Adding an Ethernet Interface end
 
 /**
  * {@link NetworkProvider} that manages NetworkOffers for Ethernet networks.
@@ -118,7 +129,114 @@ public class EthernetNetworkFactory {
         mContext = context;
         mProvider = provider;
         mDeps = deps;
+        //added by cgt Adding an Ethernet Interface start
+        mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
+        //added by cgt Adding an Ethernet Interface end
+    }
+
+    //added by cgt Adding an Ethernet Interface start
+    private EthernetManager mEthernetManager;
+    String getIpAddress(String iface) {
+        if(mEthernetManager == null){
+            mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE);
+        }
+        IpConfiguration config = mEthernetManager.getConfiguration(iface);
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            return config.getStaticIpConfiguration().ipAddress.getAddress().getHostAddress();
+        } else {
+            NetworkInterfaceState netState = mTrackingInterfaces.get(iface);
+            if (null != netState) {
+                for (LinkAddress l : netState.mLinkProperties.getLinkAddresses()) {
+                    InetAddress source = l.getAddress();
+                    //Log.d(TAG, "getIpAddress: " + source.getHostAddress());
+                    if (source instanceof Inet4Address) {
+                        return source.getHostAddress();
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    private String prefix2netmask(int prefix) {
+        // convert prefix to netmask
+        if (true) {
+            int mask = 0xFFFFFFFF << (32 - prefix);
+            //Log.d(TAG, "mask = " + mask + " prefix = " + prefix);
+            return ((mask>>>24) & 0xff) + "." + ((mask>>>16) & 0xff) + "." + ((mask>>>8) & 0xff) + "." + ((mask) & 0xff);
+        } else {
+            return NetworkUtils.intToInetAddress(NetworkUtils.prefixLengthToNetmaskInt(prefix)).getHostName();
+        }
+    }
+
+    String getNetmask(String iface) {
+        if(mEthernetManager == null){
+            mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE);
+        }
+        IpConfiguration config = mEthernetManager.getConfiguration(iface);
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            return prefix2netmask(config.getStaticIpConfiguration().ipAddress.getPrefixLength());
+        } else {
+            NetworkInterfaceState netState = mTrackingInterfaces.get(iface);
+            if (null != netState) {
+                for (LinkAddress l : netState.mLinkProperties.getLinkAddresses()) {
+                    InetAddress source = l.getAddress();
+                    if (source instanceof Inet4Address) {
+                        return prefix2netmask(l.getPrefixLength());
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    String getGateway(String iface) {
+        if(mEthernetManager == null){
+            mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE);
+        }
+        IpConfiguration config = mEthernetManager.getConfiguration(iface);
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            return config.getStaticIpConfiguration().gateway.getHostAddress();
+        } else {
+            NetworkInterfaceState netState = mTrackingInterfaces.get(iface);
+            if (null != netState) {
+                for (RouteInfo route : netState.mLinkProperties.getRoutes()) {
+                    if (route.hasGateway()) {
+                        InetAddress gateway = route.getGateway();
+                        if (route.isIPv4Default()) {
+                            return gateway.getHostAddress();
+                        }
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    /*
+     * return dns format: "8.8.8.8,4.4.4.4"
+     */
+    String getDns(String iface) {
+        if(mEthernetManager == null){
+            mEthernetManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE);
+        }
+        String dns = "";
+        IpConfiguration config = mEthernetManager.getConfiguration(iface);
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            for (InetAddress nameserver : config.getStaticIpConfiguration().dnsServers) {
+                dns += nameserver.getHostAddress() + ",";
+            }
+        } else {
+            NetworkInterfaceState netState = mTrackingInterfaces.get(iface);
+            if (null != netState) {
+                for (InetAddress nameserver : netState.mLinkProperties.getDnsServers()) {
+                    dns += nameserver.getHostAddress() + ",";
+                }
+            }
+        }
+        return dns;
     }
+    //added by cgt Adding an Ethernet Interface end
 
     /**
      * Registers the network provider with the system.

2.EthernetTracker.java类中调用EthernetNetworkFactory类中的接口,修改updateInterfaceState方法的访问范围供APP使用

+++ b/xxx/packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetTracker.java
@@ -173,6 +173,24 @@ public class EthernetTracker {
         mConfigStore = new EthernetConfigStore();
     }
 
+    //added by cgt Adding an Ethernet Interface start
+    String getIpAddress(String iface) {
+        return mFactory.getIpAddress(iface);
+    }
+
+    String getNetmask(String iface) {
+        return mFactory.getNetmask(iface);
+    }
+
+    String getGateway(String iface) {
+        return mFactory.getGateway(iface);
+    }
+
+    String getDns(String iface) {
+        return mFactory.getDns(iface);
+    }
+    //added by cgt Adding an Ethernet Interface end
+
     void start() {
         mFactory.register();
         mConfigStore.read();
@@ -533,7 +551,10 @@ public class EthernetTracker {
         }
     }
 
-    private void updateInterfaceState(String iface, boolean up) {
+    //added by cgt Adding an Ethernet Interface start
+    //private void updateInterfaceState(String iface, boolean up) {
+    public void updateInterfaceState(String iface, boolean up) {
+    //added by cgt Adding an Ethernet Interface end
         updateInterfaceState(iface, up, null /* listener */);
     }
 

3.EthernetServiceImpl.java类中调用EthernetTracker类中的接口,供给APP用

+++ b/xxx/packages/modules/Connectivity/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
@@ -122,8 +122,57 @@ public class EthernetServiceImpl extends IEthernetManager.Stub {
         // 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));
     }
 
+    //added by cgt Adding an Ethernet Interface start
+    @Override
+    public String getIpAddress(String iface) {
+        PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG);
+        if (mTracker.isRestrictedInterface(iface)) {
+            PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG);
+        }
+
+        return mTracker.getIpAddress(iface);
+    }
+
+    @Override
+    public String getNetmask(String iface) {
+        PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG);
+        if (mTracker.isRestrictedInterface(iface)) {
+            PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG);
+        }
+
+        return mTracker.getNetmask(iface);
+    }
+
+    @Override
+    public String getGateway(String iface) {
+        PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG);
+        if (mTracker.isRestrictedInterface(iface)) {
+            PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG);
+        }
+
+        return mTracker.getGateway(iface);
+    }
+
+    @Override
+    public String getDns(String iface) {
+        PermissionUtils.enforceAccessNetworkStatePermission(mContext, TAG);
+        if (mTracker.isRestrictedInterface(iface)) {
+            PermissionUtils.enforceRestrictedNetworkPermission(mContext, TAG);
+        }
+
+        return mTracker.getDns(iface);
+    }
+    //added by cgt Adding an Ethernet Interface end
+
     /**
      * Indicates whether given interface is available.
      */

三、Settings部分

        3.1、涉及修改的类

Settings/AndroidManifest.xml
Settings/res/layout/static_ip_dialog.xml
Settings/res/xml/imin_ethernet_settings.xml
Settings/res/xml/network_provider_internet.xml
Settings/src/com/android/settings/core/gateway/SettingsGateway.java
Settings/src/com/android/settings/ethernet/EtherentStaticIpDialog.java
Settings/src/com/android/settings/ethernet/EthernetSettingsPreferenceController.java
Settings/src/com/android/settings/ethernet/IminEthernetSettings.java
Settings/src/com/android/settings/ethernet/getStaticIpInfo.java

        3.2、涉及类修改的类

                Settings中添加一个界面去设置以太网相关的内容,我们可以仿照原生在网络中添加一项

                以太网设置,供用户使用,以下简略描述下实现相关。

                3.2.1、资源类

1.AndroidManifest.xml类中配置添加的以太网界面

+++ b/packages/apps/Settings/AndroidManifest.xml
@@ -801,9 +801,28 @@
                        android:value="@string/menu_key_network"/>
         </activity>
 
+        <!--added by cgt Adding an Ethernet Interface start -->
+        <activity android:name="Settings$EthernetSettingsActivity"
+            android:label="@string/ethernet_settings_title"
+            android:icon="@drawable/ic_settings_wireless"
+            android:exported="true"
+            android:taskAffinity="">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE_LAUNCH" />
+                <category android:name="com.android.settings.SHORTCUT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.ethernet.IminEthernetSettings" />
+        </activity>
+        <!--added by cgt Adding an Ethernet Interface end -->
 
         <!-- Keep compatibility with old shortcuts. -->
-        <activity-alias android:name=".TetherSettings"
+        <!--added by cgt Adding an Ethernet Interface start -->
+        <!--<activity-alias android:name=".TetherSettings" -->
+        <!--added by cgt Adding an Ethernet Interface end -->
+        <activity-alias android:name=".TestEthernetSettings"
                   android:label="@string/tether_settings_title_all"
                   android:clearTaskOnLaunch="true"
                   android:exported="true"

2.network_provider_internet.xml类中配置添加显示在网络选项中的以太网项

+++ b/Settings/res/xml/network_provider_internet.xml
@@ -108,6 +108,16 @@
         settings:userRestriction="no_config_vpn"
         settings:useAdminDisabledSummary="true" />
 
+    <!--added by cgt Adding an Ethernet Interface start -->
+    <com.android.settingslib.RestrictedPreference
+        android:fragment="com.android.settings.ethernet.TestEthernetSettings"
+        android:icon="@drawable/ic_ethernet"
+        android:key="ethernet_settings"
+        android:title="@string/ethernet_settings_title"
+        settings:useAdminDisabledSummary="true"
+        settings:userRestriction="no_ethernet_settings" />
+    <!--aadded by cgt Adding an Ethernet Interface end -->
+
     <com.android.settings.network.PrivateDnsModeDialogPreference
         android:key="private_dns_settings"
         android:title="@string/select_private_dns_configuration_title"

3.xml目录中添加imin_ethernet_settings.xml类用于显示以太网和mac地址项

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
    android:title="@string/imin_ethernet_settings" >

    <Preference
        android:key="imin_ethernet"
        android:persistent="true"
        android:summary="@string/imin_ethernet_not_connect"
        android:title="@string/imin_ethernet" />

    <Preference
        android:key="imin_ethernet_mac"
        android:summary="@string/imin_ethernet_not"
        android:title="@string/imin_ethernet_mac" />

</PreferenceScreen>

4.layout目录中添加以太网设置界面的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/imin_ethernet_bg"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#ff333333"
        android:layout_marginTop="8dp"
        android:textSize="18sp"
        android:text="@string/imin_ethernet_settings"
        android:layout_gravity="center_horizontal"/>

    <LinearLayout
        android:layout_marginTop="37dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_way"
            android:gravity="right"
            android:textColor="#ff333333"
            />

        <RadioGroup
            android:id="@+id/imin_ip_set_rg"
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:orientation="horizontal">

            <RadioButton
                android:id="@+id/imin_ip_set_dhcp_rb"
                android:layout_width="27px"
                android:layout_height="27px"
                android:background="@drawable/imin_ethernet_checkbox_selector"
                android:button="@null"
                android:gravity="center" />

            <TextView
                android:layout_marginLeft="12dp"
                android:layout_marginRight="25dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/imin_ethernet_dhcp"/>

            <RadioButton
                android:id="@+id/imin_ip_set_static_rb"
                android:layout_width="27px"
                android:layout_height="27px"
                android:layout_marginStart="10dp"
                android:background="@drawable/imin_ethernet_checkbox_selector"
                android:button="@null"
                android:gravity="center"/>
            <TextView
                android:layout_marginLeft="12dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/imin_ethernet_static"/>

        </RadioGroup>

    </LinearLayout>

    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_address"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_ip_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                android:hint="192.168.1.148"/>
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_mask"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_mask_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                android:hint="255.255.255.0"/>
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_dns"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_dns_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                android:hint="192.168.1.1"/>
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_gateway"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_gateway_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                android:hint="192.168.1.1"/>
        </RelativeLayout>
    </LinearLayout>


    <LinearLayout
        android:layout_marginTop="27dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_agency"
            />

        <RadioGroup
            android:id="@+id/imin_agency_rg"
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:orientation="horizontal"
            android:layout_height="wrap_content">

            <RadioButton
                android:id="@+id/imin_agency_not_rb"
                android:layout_width="27px"
                android:layout_height="27px"
                android:background="@drawable/imin_ethernet_checkbox_selector"
                android:button="@null"
                android:gravity="center" />

            <TextView
                android:layout_marginLeft="12dp"
                android:layout_marginRight="25dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/imin_ethernet_not"/>

            <RadioButton
                android:id="@+id/imin_agency_manual_rb"
                android:layout_width="27px"
                android:layout_height="27px"
                android:layout_marginStart="10dp"
                android:background="@drawable/imin_ethernet_checkbox_selector"
                android:button="@null"
                android:gravity="center"/>

            <TextView
                android:layout_marginLeft="12dp"
                android:layout_marginRight="25dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/imin_ethernet_manual"/>
            <RadioButton
                android:id="@+id/imin_agency_auto_rb"
                android:layout_width="27px"
                android:layout_height="27px"
                android:layout_marginStart="10dp"
                android:background="@drawable/imin_ethernet_checkbox_selector"
                android:button="@null"
                android:gravity="center"/>
            <TextView
                android:layout_marginLeft="12dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/imin_ethernet_auto"/>
        </RadioGroup>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/imin_host_ll"
        android:visibility="gone"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_host"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_host_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                android:hint="Proxy.example.com"/>
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/imin_port_ll"
        android:visibility="gone"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_port"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_port_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:digits="0123456789"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                android:hint="8080"/>
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/imin_proxy_ll"
        android:visibility="gone"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_proxy"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_proxy_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                android:hint="example.com,localhose"/>
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/imin_pac_ll"
        android:visibility="gone"
        android:layout_marginTop="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:textColor="#ff333333"
            android:gravity="right"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/imin_ethernet_pac"
            />
        <RelativeLayout
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="3"
            android:layout_height="26dp">
            <EditText
                android:id="@+id/imin_pac_et"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:textSize="14sp"
                android:layout_marginRight="30dp"
                android:background="@drawable/imin_ethernet_input"
                android:paddingLeft="14dp"
                />
        </RelativeLayout>
    </LinearLayout>

    <Button
        android:id="@+id/imin_confirm_bt"
        android:layout_marginTop="27dp"
        android:layout_width="72dp"
        android:layout_height="35dp"
        android:layout_gravity="center_horizontal"
        android:text="@string/imin_ethernet_confirm"
        android:textColor="@android:color/holo_red_dark"
        android:textSize="12sp"
        android:background="@drawable/imin_ethernet_button_selector"
        />


</LinearLayout>
                3.2.2、源码实现类

1.SettingsGateway.java类中添加设置界面进入设置网络主页

+++ b/xxx/Settings/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -190,6 +190,9 @@ import com.mediatek.settings.advancedcalling.AdvancedWifiCallingSettings;
 import com.mediatek.hdmi.HdmiSettings;
 /// M: Add for wfd settings fragment.
 import com.mediatek.settings.wfd.WfdSinkSurfaceFragment;
+//added by cgt Adding an Ethernet Interface start
+import com.android.settings.ethernet.IminEthernetSettings;
+//added by cgt Adding an Ethernet Interface end
 
 public class SettingsGateway {
 
@@ -214,6 +217,9 @@ public class SettingsGateway {
             WifiTetherSettings.class.getName(),
             BackgroundCheckSummary.class.getName(),
             VpnSettings.class.getName(),
+            //added by cgt Adding an Ethernet Interface start
+            TestEthernetSettings.class.getName(),
+            //added by cgt Adding an Ethernet Interface end
             DataSaverSummary.class.getName(),
             DateTimeSettings.class.getName(),
             LocaleListEditor.class.getName(),

2.添加TestEthernetSettings.java类实现设置代码

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.ethernet;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.EthernetManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.LinkAddress;
import android.net.NetworkInfo;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.preference.CheckBoxPreference;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

import androidx.preference.ListPreference;
import androidx.preference.Preference;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.io.FileReader;
import java.io.IOException;
import android.util.DisplayMetrics;
import android.view.Window;

/*for 5.0*/
//import android.preference.ListPreference;
//import com.android.internal.logging.MetricsProto.MetricsEvent;

public class TestEthernetSettings extends SettingsPreferenceFragment
        implements Preference.OnPreferenceClickListener {
    private static final String TAG = "TestEthernetSettings";

    public enum ETHERNET_STATE {
        ETHER_STATE_DISCONNECTED,
        ETHER_STATE_CONNECTING,
        ETHER_STATE_CONNECTED
    }

    private static final String KEY_ETH_test = "test_ethernet";
    private static final String KEY_ETH_MAC = "test_ethernet_mac";
    private static String mEthHwAddress = null;
    private static String mEthIpAddress = null;
    private static String mEthNetmask = null;
    private static String mEthGateway = null;
    private static String mEthdns1 = null;
    private static String mEthdns2 = null;
    private final static String nullIpInfo = "0.0.0.0";

    private Preference mkeyEthMode;
    private final IntentFilter mIntentFilter;
    IpConfiguration mIpConfiguration;
    EthernetManager mEthManager;
    StaticIpConfiguration mStaticIpConfiguration;
    Context mContext;
    private String mIfaceName;
    private long mChangeTime;
    private static final int SHOW_RENAME_DIALOG = 0;
    private static final int ETHER_IFACE_STATE_DOWN = 0;
    private static final int ETHER_IFACE_STATE_UP = 1;

    private static final String FILE = "/sys/class/net/eth0/flags";
    private static final int MSG_GET_ETHERNET_STATE = 0;

    private EditText test_ip_et = null;
    private EditText test_mask_et = null;
    private EditText test_dns_et = null;
    private EditText test_gateway_et = null;
    private EditText test_host_et = null;
    private EditText test_port_et = null;
    private EditText test_proxy_et = null;
    private EditText test_pac_et = null;
    private RadioButton test_ip_set_dhcp_rb = null;
    private RadioButton test_ip_set_static_rb = null;
    private RadioButton test_agency_not_rb = null;
    private RadioButton test_agency_manual_rb = null;
    private RadioButton test_agency_auto_rb = null;
    private Dialog alertDialog = null;
    private LinearLayout test_host_ll = null;
    private LinearLayout test_port_ll = null;
    private LinearLayout test_proxy_ll = null;
    private LinearLayout test_pac_ll = null;
    private boolean isStaticMode  = false;

    private boolean mCurrentModeIsStatic  = false;
    private String mEthTempIpAddress = null;
    private String mEthTempNetmask = null;
    private String mEthTempGateway = null;
    private String mEthTempdns1 = null;
    private static String mEthTempdns2 = null;

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.WIFI_TETHER_SETTINGS;
    }

    @Override
    public int getDialogMetricsCategory(int dialogId) {
        switch (dialogId) {
            case SHOW_RENAME_DIALOG:
                return MetricsEvent.WIFI_TETHER_SETTINGS;
            default:
                return 0;
        }
    }
    public TestEthernetSettings() {
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.test_ethernet_settings);

        mContext = this.getActivity().getApplicationContext();
        mEthManager = (EthernetManager) getSystemService(Context.ETHERNET_SERVICE);

        if (mEthManager == null) {
            Log.e(TAG, "get ethernet manager failed");
            Toast.makeText(mContext, R.string.disabled_feature, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
        String[] ifaces = mEthManager.getAvailableInterfaces();
        for(int i = 0; i < ifaces.length; i++){
            Log.e(TAG, "TestEthernetSettings iface= " + ifaces[i]);
        }
        if (ifaces.length > 0) {
            mIfaceName = ifaces[0];//"eth0";
        }
        if (null == mIfaceName) {
            Log.e(TAG, "get ethernet ifaceName failed");
            Toast.makeText(mContext, R.string.disabled_feature, Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (null == mIfaceName) {
            return;
        }
        if (mkeyEthMode == null) {
            mkeyEthMode = (Preference) findPreference(KEY_ETH_test);
            mkeyEthMode.setOnPreferenceClickListener(this);
        }
        setStringSummary(KEY_ETH_MAC, getEthernetMacAddress());
        log("resume");
        mContext.registerReceiver(mReceiver, mIntentFilter);
    }

    @Override
    public void onPause() {
        super.onPause();
        log("onPause");
        if (null == mIfaceName) {
            return;
        }

        //setIPSettingMode();
        //setProxyInfo();
        mContext.unregisterReceiver(mReceiver);
		if(alertDialog != null){
			alertDialog.dismiss();
		}
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeMessages(MSG_GET_ETHERNET_STATE);
        log("destory");
    }

    @Override
    public void onStop() {
        super.onStop();
        log("stop");
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            log("Action " + action);
            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
                NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                Log.v(TAG, "===" + info.toString());
                if (null != info && ConnectivityManager.TYPE_ETHERNET == info.getType()) {
                    long currentTime = System.currentTimeMillis();
                    int delayTime = 0;
                    if (currentTime - mChangeTime < 1000) {
                        delayTime = 2000;
                    }
                    if (NetworkInfo.State.CONNECTED == info.getState()) {
                        handleEtherStateChange(ETHERNET_STATE.ETHER_STATE_CONNECTED, delayTime);
                    } else if (NetworkInfo.State.DISCONNECTED == info.getState()) {
                        handleEtherStateChange(ETHERNET_STATE.ETHER_STATE_DISCONNECTED, delayTime);
                    }
                }
            }
        }
    };

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (MSG_GET_ETHERNET_STATE == msg.what) {
                handleEtherStateChange((ETHERNET_STATE) msg.obj);
            }
        }
    };

    private void handleEtherStateChange(ETHERNET_STATE EtherState, long delayMillis) {
        mHandler.removeMessages(MSG_GET_ETHERNET_STATE);
        if (delayMillis > 0) {
            Message msg = new Message();
            msg.what = MSG_GET_ETHERNET_STATE;
            msg.obj = EtherState;
            mHandler.sendMessageDelayed(msg, delayMillis);
        } else {
            handleEtherStateChange(EtherState);
        }
    }

    private void handleEtherStateChange(ETHERNET_STATE EtherState) {
        log("curEtherState" + EtherState);

        switch (EtherState) {
            case ETHER_STATE_DISCONNECTED:
                mEthHwAddress = nullIpInfo;
                mEthIpAddress = nullIpInfo;
                mEthNetmask = nullIpInfo;
                mEthGateway = nullIpInfo;
                mEthdns1 = nullIpInfo;
                mEthdns2 = nullIpInfo;
                break;
            case ETHER_STATE_CONNECTING:
                //modify by luoyalong for Eth and WLAN control 20220530 begin
                String way = Settings.System.getString(mContext.getContentResolver() , "test_ip_way");
                IpAssignment mode = way != null&& way.equals("static") ? IpAssignment.STATIC : IpAssignment.DHCP;
                log("IES refreshtestUI way= " + way + " , mode= " + mode);
                log("handleEtherStateChange mode= " + mode);
                if (mode == IpAssignment.DHCP) {
                    String mStatusString = this.getResources().getString(R.string.ethernet_info_getting);
                    mEthHwAddress = mStatusString;
                    mEthIpAddress = mStatusString;
                    mEthNetmask = mStatusString;
                    mEthGateway = mStatusString;
                    mEthdns1 = mStatusString;
                    mEthdns2 = mStatusString;
                }else{
                    getEthInfo();
                }
                //modify by luoyalong for Eth and WLAN control 20220530 end
                break;
            case ETHER_STATE_CONNECTED:
                getEthInfo();
                break;
        }
        if(isAdded()){
            refreshtestUI();
        }
    }

    private void refreshtestUI(){
        ConnectivityManager mConnectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
        if(mNetworkInfo != null && mNetworkInfo.isConnected() && !(mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI)){
            String connected = this.getResources().getString(R.string.network_connected);
            setStringSummary(KEY_ETH_test, connected);
        }else{
            String notConnected = this.getResources().getString(R.string.test_ethernet_not_connect);
            setStringSummary(KEY_ETH_test, notConnected);
        }

        if(test_ip_et != null){
            String way = Settings.System.getString(mContext.getContentResolver() , "test_ip_way");
            IpAssignment mode = way != null&& way.equals("static") ? IpAssignment.STATIC : IpAssignment.DHCP;
            log("IES refreshtestUI way= " + way + " , mode= " + mode);
            if (mode == IpAssignment.STATIC) {
                isStaticMode = true;

                test_ip_set_static_rb.setChecked(true);
                test_ip_et.setEnabled(true);
                test_mask_et.setEnabled(true);
                test_dns_et.setEnabled(true);
                test_gateway_et.setEnabled(true);
            } else {
                isStaticMode = false;
                test_ip_set_dhcp_rb.setChecked(true);
                test_ip_et.setEnabled(false);
                test_mask_et.setEnabled(false);
                test_dns_et.setEnabled(false);
                test_gateway_et.setEnabled(false);
            }

            String host = Settings.System.getString(mContext.getContentResolver() , "test_proxy_host");
            String port = Settings.System.getString(mContext.getContentResolver() , "test_proxy_port");
            String exclList = Settings.System.getString(mContext.getContentResolver() , "test_proxy_exclList");
            String uri = Settings.System.getString(mContext.getContentResolver() , "test_proxy_uri");
            log("refreshtestUI  host: = " + host
                + " , port: = " + port
                + " , exclList: = " + exclList
                + " , uri: = " + uri);
            String mHost = test_host_et.getText().toString();
            String mPort = test_port_et.getText().toString();
            String mExclList = test_proxy_et.getText().toString();
            String uriString = test_pac_et.getText().toString();
            if(!"".equals(mHost)){
                host = mHost;
            }
            if(!"".equals(mPort)){
                port = mPort;
            }
            if(!"".equals(mExclList)){
                exclList = mExclList;
            }
            if(!"".equals(uriString)){
                uri = uriString;
            }
            if(!"".equals(host)&& host != null){
                test_host_et.setText(host);
            }
            if(!"".equals(port)&& port != null){
                test_port_et.setText(port);
            }
            if(!"".equals(exclList)&& exclList != null){
                test_proxy_et.setText(exclList);
            }
            if(!"".equals(uri)&& uri != null){
                test_pac_et.setText(uri);
            }

            int agency = Settings.System.getInt(mContext.getContentResolver() , "test_agency_select" , 0);
            test_host_ll.setVisibility(View.GONE);
            test_port_ll.setVisibility(View.GONE);
            test_proxy_ll.setVisibility(View.GONE);
            test_pac_ll.setVisibility(View.GONE);
            if(agency == 1){
                test_pac_ll.setVisibility(View.VISIBLE);
                test_agency_auto_rb.setChecked(true);
            }else if(agency == 2){
                test_host_ll.setVisibility(View.VISIBLE);
                test_port_ll.setVisibility(View.VISIBLE);
                test_proxy_ll.setVisibility(View.VISIBLE);
                test_agency_manual_rb.setChecked(true);
            }else{
                test_agency_not_rb.setChecked(true);
            }
            test_ip_et.setText(mEthIpAddress);
            test_mask_et.setText(mEthNetmask);
            test_gateway_et.setText(mEthGateway);
            test_dns_et.setText(mEthdns1);
        }
        log("refreshtestUI 380 mEthIpAddress= " + mEthIpAddress
                + " , mEthGateway= " + mEthGateway
                + " , mEthdns1= " + mEthdns1
                + " , mEthNetmask= " + mEthNetmask);

    }

    private void settestEtherentDialog() {
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
		//modify by luoyalong for bug 5040 eth UI problem 20230308 begin
        View view =null; 
		DisplayMetrics d2 = this.getResources().getDisplayMetrics();
		if(d2.density > 2.0){
			view =layoutInflater.inflate(R.layout.test_ethernet_dialog_2d, null);
		}else{
			view =layoutInflater.inflate(R.layout.test_ethernet_dialog, null);
		}
		//modify by luoyalong for bug 5040 eth UI problem 20230308 end
        RadioGroup test_ip_set_rg = view.findViewById(R.id.test_ip_set_rg);
        test_ip_set_dhcp_rb = view.findViewById(R.id.test_ip_set_dhcp_rb);
        test_ip_set_static_rb = view.findViewById(R.id.test_ip_set_static_rb);
        test_ip_et = view.findViewById(R.id.test_ip_et);
        test_mask_et = view.findViewById(R.id.test_mask_et);
        test_dns_et = view.findViewById(R.id.test_dns_et);
        test_gateway_et = view.findViewById(R.id.test_gateway_et);
        RadioGroup test_agency_rg = view.findViewById(R.id.test_agency_rg);
        test_agency_not_rb = view.findViewById(R.id.test_agency_not_rb);
        test_agency_manual_rb = view.findViewById(R.id.test_agency_manual_rb);
        test_agency_auto_rb = view.findViewById(R.id.test_agency_auto_rb);
        test_host_ll = view.findViewById(R.id.test_host_ll);
        test_host_et = view.findViewById(R.id.test_host_et);
        test_port_ll = view.findViewById(R.id.test_port_ll);
        test_port_et = view.findViewById(R.id.test_port_et);
        test_proxy_ll = view.findViewById(R.id.test_proxy_ll);
        test_proxy_et = view.findViewById(R.id.test_proxy_et);
        test_pac_ll = view.findViewById(R.id.test_pac_ll);
        test_pac_et = view.findViewById(R.id.test_pac_et);
        Button test_confirm_bt = view.findViewById(R.id.test_confirm_bt);

        mEthIpAddress = mEthNetmask = mEthGateway = mEthdns1 = "";
        getEthInfo();

        refreshtestUI();

        test_ip_set_rg.setOnCheckedChangeListener((group, checkedId) -> {
            //handleEtherStateChange(TestEthernetSettings.ETHERNET_STATE.ETHER_STATE_CONNECTING);
            if(checkedId == test_ip_set_dhcp_rb.getId()){

                mEthTempIpAddress = test_ip_et.getText().toString();
                mEthTempGateway = test_gateway_et.getText().toString();
                mEthTempdns1 = test_dns_et.getText().toString();
                mEthTempNetmask = test_mask_et.getText().toString();
                getEthInfo();
                log("setOnCheckedChangeListener dhcp mEthIpAddress= " + mEthIpAddress
                                + " , mEthGateway= " + mEthGateway
                                + " , mEthdns1= " + mEthdns1
                                + " , mEthNetmask= " + mEthNetmask + " mEthTempIpAddress= " + mEthTempIpAddress
                                + " , mEthTempGateway= " + mEthTempGateway
                                + " , mEthTempdns1= " + mEthTempdns1
                                + " , mEthTempNetmask= " + mEthTempNetmask);
                test_ip_et.setText(mEthIpAddress);
                test_mask_et.setText(mEthNetmask);
                test_gateway_et.setText(mEthGateway);
                test_dns_et.setText(mEthdns1);

                test_ip_et.setEnabled(false);
                test_mask_et.setEnabled(false);
                test_dns_et.setEnabled(false);
                test_gateway_et.setEnabled(false);
                mChangeTime = System.currentTimeMillis();

            }else{

                getEthInfo();
                log("setOnCheckedChangeListener static mEthIpAddress= " + mEthIpAddress
                                + " , mEthGateway= " + mEthGateway
                                + " , mEthdns1= " + mEthdns1
                                + " , mEthNetmask= " + mEthNetmask + " mEthTempIpAddress= " + mEthTempIpAddress
                                + " , mEthTempGateway= " + mEthTempGateway
                                + " , mEthTempdns1= " + mEthTempdns1
                                + " , mEthTempNetmask= " + mEthTempNetmask);
                if (mEthTempIpAddress != null) {
                    mEthIpAddress = mEthTempIpAddress;
                }
                if (mEthTempGateway != null) {
                    mEthGateway = mEthTempGateway;
                }
                if (mEthTempdns1 != null) {
                    mEthdns1 = mEthTempdns1;
                }
                if (mEthTempNetmask != null) {
                    mEthNetmask = mEthTempNetmask;
                }
                test_ip_et.setText(mEthIpAddress);
                test_mask_et.setText(mEthNetmask);
                test_gateway_et.setText(mEthGateway);
                test_dns_et.setText(mEthdns1);

                test_ip_et.setEnabled(true);
                test_mask_et.setEnabled(true);
                test_dns_et.setEnabled(true);
                test_gateway_et.setEnabled(true);

            }
        });

        test_agency_rg.setOnCheckedChangeListener((group, checkedId) -> {
            test_host_ll.setVisibility(View.GONE);
            test_port_ll.setVisibility(View.GONE);
            test_proxy_ll.setVisibility(View.GONE);
            test_pac_ll.setVisibility(View.GONE);
            Settings.System.putInt(mContext.getContentResolver() , "test_agency_select" , 0);
            if(checkedId == test_agency_auto_rb.getId()){
                test_pac_ll.setVisibility(View.VISIBLE);
                Settings.System.putInt(mContext.getContentResolver() , "test_agency_select" , 1);
            }else if(checkedId == test_agency_manual_rb.getId()){
                test_host_ll.setVisibility(View.VISIBLE);
                test_port_ll.setVisibility(View.VISIBLE);
                test_proxy_ll.setVisibility(View.VISIBLE);
                Settings.System.putInt(mContext.getContentResolver() , "test_agency_select" , 2);
            }
        });

        test_confirm_bt.setOnClickListener(v -> {
            log("cliked confirm button" );

            setEthernetSettings();

            alertDialog.dismiss();
        });

        alertDialog = new AlertDialog.Builder(mContext).setView(view).create();
        alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
		Window dialogWindow = alertDialog.getWindow();
        WindowManager.LayoutParams lp = dialogWindow.getAttributes();
        DisplayMetrics d = this.getResources().getDisplayMetrics();
        alertDialog.show();
		if(d.density > 1.6){
			if(d.scaledDensity > 2.0){
				alertDialog.getWindow().setLayout(840, 1320);
			}else{
			    alertDialog.getWindow().setLayout(840, 1160);
		    }
		}else{
			alertDialog.getWindow().setLayout(760, 800);
		}
    }


    private void setStringSummary(String preference, String value) {
        try {
            findPreference(preference).setSummary(value);
        } catch (RuntimeException e) {
            findPreference(preference).setSummary("");
            log("can't find " + preference);
        }
    }

    private void setProxyInfo(){
        IpAssignment ipAssignment = test_ip_set_static_rb.isChecked() ? IpAssignment.STATIC : IpAssignment.DHCP;
        log("setProxyInfo 431 ipAssignment= " + ipAssignment + " , isStaticMode : " + isStaticMode);
        if(test_agency_manual_rb.isChecked()){
            String host = test_host_et.getText().toString();
            String port = test_port_et.getText().toString();
            String exclList = test_proxy_et.getText().toString();
            log("setProxyInfo 440 host= " + host + " , port= " + port + " , exclList= " + exclList);
            if("".equals(host) || "".equals(port) || "".equals(exclList)){
                Toast.makeText(mContext , R.string.test_ethernet_manual_setup_failed , Toast.LENGTH_LONG).show();
                return;
            }
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_host" , host);
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_port" , port);
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_exclList" , exclList);
            ProxyInfo proxyInfo = new ProxyInfo(host, Integer.parseInt(port), exclList);
            if(checkIPValue()){
                mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.STATIC, isStaticMode ? mStaticIpConfiguration:null, proxyInfo));
            }
        }else if(test_agency_auto_rb.isChecked()){
            String uriString = test_pac_et.getText().toString();
            log("setProxyInfo 449  uriString= " + uriString);
            if("".equals(uriString)){
                Toast.makeText(mContext , R.string.test_ethernet_address_setup_failed , Toast.LENGTH_LONG).show();
                return;
            }
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_uri" , uriString);
            Uri uri = Uri.parse(uriString);
            ProxyInfo proxyInfo = new ProxyInfo(uri);
            if(checkIPValue()){
                mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.PAC, isStaticMode ? mStaticIpConfiguration:null, proxyInfo));
            }
        }else{
            log("setProxyInfo null = ");
            if(checkIPValue()){
                mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.NONE, isStaticMode ? mStaticIpConfiguration:null, null));
            }
        }
    }

    private void setEthernetProxyInfo(){
        IpAssignment ipAssignment = mCurrentModeIsStatic ? IpAssignment.STATIC : IpAssignment.DHCP;
        log("setEthernetProxyInfo 431 ipAssignment= " + ipAssignment + " , mCurrentModeIsStatic : " + mCurrentModeIsStatic);
        if(test_agency_manual_rb.isChecked()){
            String host = test_host_et.getText().toString();
            String port = test_port_et.getText().toString();
            String exclList = test_proxy_et.getText().toString();
            log("setProxyInfo 440 host= " + host + " , port= " + port + " , exclList= " + exclList);
            if("".equals(host) || "".equals(port) || "".equals(exclList)){
                Toast.makeText(mContext , R.string.test_ethernet_manual_setup_failed , Toast.LENGTH_LONG).show();
                return;
            }
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_host" , host);
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_port" , port);
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_exclList" , exclList);
            ProxyInfo proxyInfo = new ProxyInfo(host, Integer.parseInt(port), exclList);
            mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.STATIC, mCurrentModeIsStatic ? mStaticIpConfiguration:null, proxyInfo));
        }else if(test_agency_auto_rb.isChecked()){
            String uriString = test_pac_et.getText().toString();
            log("setProxyInfo 449  uriString= " + uriString);
            if("".equals(uriString)){
                Toast.makeText(mContext , R.string.test_ethernet_address_setup_failed , Toast.LENGTH_LONG).show();
                return;
            }
            Settings.System.putString(mContext.getContentResolver() , "test_proxy_uri" , uriString);
            Uri uri = Uri.parse(uriString);
            ProxyInfo proxyInfo = new ProxyInfo(uri);
            mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.PAC, mCurrentModeIsStatic ? mStaticIpConfiguration:null, proxyInfo));
        }else{
            log("setEthernetProxyInfo null = ");
            mEthManager.setConfiguration(mIfaceName, new IpConfiguration(ipAssignment, ProxySettings.NONE, mCurrentModeIsStatic ? mStaticIpConfiguration:null, null));
        }
    }

    public boolean checkEthernetSettings() {
        boolean enable = false;
        mEthIpAddress = test_ip_et.getText().toString();
        mEthGateway = test_gateway_et.getText().toString();
        mEthdns1 = test_dns_et.getText().toString();
        mEthNetmask = test_mask_et.getText().toString();
        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$"); /*check subnet mask*/
        log(" ** checkEthernetSettings mEthIpAddress= " + mEthIpAddress
                + " , mEthGateway= " + mEthGateway
                + " , mEthdns1= " + mEthdns1
                + " , mEthNetmask= " + mEthNetmask
                + " , isValidIpAddress mEthIpAddress= " + isValidIpAddress(mEthIpAddress)
                + " , isValidIpAddress mEthGateway= " + isValidIpAddress(mEthGateway)
                + " , isValidIpAddress mEthdns1= " + isValidIpAddress(mEthdns1)
                + " , matches= " + pattern.matcher(mEthNetmask).matches());
        if (isValidIpAddress(mEthIpAddress) && isValidIpAddress(mEthGateway)
                && isValidIpAddress(mEthdns1) && (pattern.matcher(mEthNetmask).matches())) {
            enable = true;
        } else {
            enable = false;
        }
        if (mEthIpAddress != null && mEthGateway != null && mEthIpAddress.equals(mEthGateway)) {
            enable = false;
        }
        return enable;

    }
    private void setEthernetSettings() {
        log("setEthernetSettings  = ");
        if(test_ip_set_static_rb.isChecked()){
            if(checkEthernetSettings()){
                if (setStaticIpConfiguration()) {
                    mChangeTime = System.currentTimeMillis();
                    Settings.System.putString(mContext.getContentResolver() , "test_ip_way" , "static");
                    mCurrentModeIsStatic = true;
                    mEthManager.setConfiguration(mIfaceName, mIpConfiguration);
                    log("setEthernetSettings  static is checked , setConfiguration static ");
                    handleEtherStateChange(TestEthernetSettings.ETHERNET_STATE.ETHER_STATE_CONNECTING);
                    setEthernetProxyInfo();
                } else {
                    Toast.makeText(mContext , R.string.test_ethernet_static_ip_setup_failed , Toast.LENGTH_LONG).show();
                }
            } else{
                Toast.makeText(mContext , R.string.test_ethernet_parameter_exception , Toast.LENGTH_LONG).show();
            }
        }else if(test_ip_set_dhcp_rb.isChecked()){
            log("setEthernetSettings  dhcp is checked , setConfiguration DHCP ");
            Settings.System.putString(mContext.getContentResolver() , "test_ip_way" , "dhcp");
            mCurrentModeIsStatic = false;
            mEthManager.setConfiguration(mIfaceName, new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null));
            setEthernetProxyInfo();
        }
    }

    private void setIPSettingMode(){
        log("setIPSettingMode  = ");
        if(test_ip_set_static_rb.isChecked()){
            if(checkIPValue()){
                if (setStaticIpConfiguration()) {
                    mChangeTime = System.currentTimeMillis();
                    mEthManager.setConfiguration(mIfaceName, mIpConfiguration);
                    handleEtherStateChange(TestEthernetSettings.ETHERNET_STATE.ETHER_STATE_CONNECTING);
                } else {
                    Toast.makeText(mContext , R.string.test_ethernet_static_ip_setup_failed , Toast.LENGTH_LONG).show();
                }
            }else{
                log("setIPSettingMode  setConfiguration DHCP= ");
                mEthManager.setConfiguration(mIfaceName, new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null));
            }
        }else if(test_ip_set_dhcp_rb.isChecked()){
            log("setIPSettingMode  dhcp is checked , setConfiguration DHCP ");
            mEthManager.setConfiguration(mIfaceName, new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null));
        }
    }

    private String getEthernetMacAddress() {
        BufferedReader reader = null;
        String ethernetMac =null;
        try {
            reader = new BufferedReader(new FileReader("sys/class/net/eth0/address"));
            ethernetMac = reader.readLine();
            Log.v("hg", "ethernetMac: " + ethernetMac.toString());
        } catch (Exception e) {
            Log.e("hg", "open sys/class/net/eth0/address failed : " + e);
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException e) {
                Log.e("hg", "close sys/class/net/eth0/address failed : " + e);
            }
        }
        return ethernetMac.toString();
    }

    public boolean checkIPValue() {
        boolean enable = false;
        mEthIpAddress = test_ip_et.getText().toString();
        mEthGateway = test_gateway_et.getText().toString();
        mEthdns1 = test_dns_et.getText().toString();
        mEthNetmask = test_mask_et.getText().toString();
        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$"); /*check subnet mask*/
        log(" ** checkIPValue mEthIpAddress= " + mEthIpAddress
                + " , mEthGateway= " + mEthGateway
                + " , mEthdns1= " + mEthdns1
                + " , mEthNetmask= " + mEthNetmask
                + " , isValidIpAddress mEthIpAddress= " + isValidIpAddress(mEthIpAddress)
                + " , isValidIpAddress mEthGateway= " + isValidIpAddress(mEthGateway)
                + " , isValidIpAddress mEthdns1= " + isValidIpAddress(mEthdns1)
                + " , matches= " + pattern.matcher(mEthNetmask).matches());
        if (isValidIpAddress(mEthIpAddress) && isValidIpAddress(mEthGateway)
                && isValidIpAddress(mEthdns1) && (pattern.matcher(mEthNetmask).matches())) {
            enable = true;
        } else {
            Toast.makeText(mContext , R.string.test_ethernet_parameter_exception , Toast.LENGTH_LONG).show();
            enable = false;
        }
        return enable;

    }

    private Inet4Address getIPv4Address(String text) {
        try {
            return (Inet4Address) EthernetManager.testNumericToInetAddress(text);
        } catch (IllegalArgumentException | ClassCastException e) {
            return null;
        }
    }

    /*
     * 返回 指定的 String 是否是 有效的 IP 地址.
     */
    private boolean isValidIpAddress(String value) {
        int start = 0;
        int end = value.indexOf('.');
        int numBlocks = 0;
        if(nullIpInfo.equals(value)){
            return false;
        }

        while (start < value.length()) {

            if (-1 == end) {
                end = value.length();
            }

            try {
                int block = Integer.parseInt(value.substring(start, end));
                if ((block > 255) || (block < 0)) {
                    Log.w("EthernetIP",
                            "isValidIpAddress() : invalid 'block', block = "
                                    + block);
                    return false;
                }
            } catch (NumberFormatException e) {
                Log.w("EthernetIP", "isValidIpAddress() : e = " + e);
                return false;
            }

            numBlocks++;

            start = end + 1;
            end = value.indexOf('.', start);
        }
        return numBlocks == 4;
    }

    @Override
    public boolean onPreferenceClick(Preference preference) {
        log("onPreferenceClick");
        if (preference == mkeyEthMode) {
            settestEtherentDialog();
        }
        return true;
    }


    //将子网掩码转换成ip子网掩码形式,比如输入32输出为255.255.255.255
    public String interMask2String(int prefixLength) {
        String netMask = null;
        int inetMask = prefixLength;

        int part = inetMask / 8;
        int remainder = inetMask % 8;
        int sum = 0;

        for (int i = 8; i > 8 - remainder; i--) {
            sum = sum + (int) Math.pow(2, i - 1);
        }

        if (part == 0) {
            netMask = sum + ".0.0.0";
        } else if (part == 1) {
            netMask = "255." + sum + ".0.0";
        } else if (part == 2) {
            netMask = "255.255." + sum + ".0";
        } else if (part == 3) {
            netMask = "255.255.255." + sum;
        } else if (part == 4) {
            netMask = "255.255.255.255";
        }

        return netMask;
    }

    /*
     * convert subMask string to prefix length
     */
    private int maskStr2InetMask(String maskStr) {
        StringBuffer sb;
        String str;
        int inetmask = 0;
        int count = 0;
        /*
         * check the subMask format
         */
        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
        log("595 maskStr2InetMask pattern= " + pattern
                + " , maskStr= " + maskStr);
        if (pattern.matcher(maskStr).matches() == false) {
            Log.e(TAG, "subMask is error");
            return 0;
        }

        String[] ipSegment = maskStr.split("\\.");
        for (int n = 0; n < ipSegment.length; n++) {
            sb = new StringBuffer(Integer.toBinaryString(Integer.parseInt(ipSegment[n])));
            str = sb.reverse().toString();
            count = 0;
            for (int i = 0; i < str.length(); i++) {
                i = str.indexOf("1", i);
                if (i == -1)
                    break;
                count++;
            }
            inetmask += count;
        }
        return inetmask;
    }

    private void saveIpSettingInfo(){
        Settings.System.putString(mContext.getContentResolver() , "test_static_ipaddress" , this.mEthIpAddress);
        Settings.System.putString(mContext.getContentResolver() , "test_static_mask" , this.mEthNetmask);
        Settings.System.putString(mContext.getContentResolver() , "test_static_gateway" , this.mEthGateway);
        Settings.System.putString(mContext.getContentResolver() , "test_static_dns1" , this.mEthdns1);
    }

    private boolean setStaticIpConfiguration() {
        //mStaticIpConfiguration = new StaticIpConfiguration();
        /*
         * get ip address, netmask,dns ,gw etc.
         */
        Inet4Address inetAddr = getIPv4Address(this.mEthIpAddress);
        int prefixLength = maskStr2InetMask(this.mEthNetmask);
        InetAddress gatewayAddr = getIPv4Address(this.mEthGateway);
        InetAddress dnsAddr = getIPv4Address(this.mEthdns1);
        if (inetAddr.getAddress().toString().isEmpty() || prefixLength == 0 || gatewayAddr.toString().isEmpty()
                || dnsAddr.toString().isEmpty()) {
            log("ip,mask or dnsAddr is wrong");
            return false;
        }


        saveIpSettingInfo();
        /*mStaticIpConfiguration.setIpAddress(new LinkAddress(inetAddr, prefixLength));
        mStaticIpConfiguration.setGateway(gatewayAddr);
        mStaticIpConfiguration.addDnsServers(dnsAddr);*/

        List<InetAddress> dnsAddrs = new ArrayList<InetAddress>();
        dnsAddrs.add(dnsAddr);
        if(mEthdns2 != null){
            dnsAddrs.add(getIPv4Address(mEthdns2));
        }

        mStaticIpConfiguration = new StaticIpConfiguration.Builder()
                .setIpAddress(new LinkAddress(inetAddr, prefixLength))
                .setGateway(gatewayAddr)
                .setDnsServers(dnsAddrs)
                .build();
        mIpConfiguration = new IpConfiguration();
        mIpConfiguration.setIpAssignment(IpAssignment.STATIC);
        mIpConfiguration.setProxySettings(ProxySettings.NONE);
        mIpConfiguration.setStaticIpConfiguration(mStaticIpConfiguration);
        log("Complete static ip Settings ....");
        return true;
    }

    public void getEthInfoFromDhcp() {
        String tempIpInfo;

        tempIpInfo = /*SystemProperties.get("dhcp."+ iface +".ipaddress");*/
                mEthManager.getIpAddress(mIfaceName);

        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
            mEthIpAddress = tempIpInfo;
        } else {
            mEthIpAddress = nullIpInfo;
        }

        tempIpInfo = /*SystemProperties.get("dhcp."+ iface +".mask");*/
                mEthManager.getNetmask(mIfaceName);
        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
            mEthNetmask = tempIpInfo;
        } else {
            mEthNetmask = nullIpInfo;
        }

        tempIpInfo = /*SystemProperties.get("dhcp."+ iface +".gateway");*/
                mEthManager.getGateway(mIfaceName);
        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
            mEthGateway = tempIpInfo;
        } else {
            mEthGateway = nullIpInfo;
        }

        tempIpInfo = /*SystemProperties.get("dhcp."+ iface +".dns1");*/
                mEthManager.getDns(mIfaceName);
        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
            String data[] = tempIpInfo.split(",");
            mEthdns1 = data[0];
            if (data.length <= 1) {
                mEthdns2 = nullIpInfo;
            } else {
                mEthdns2 = data[1];
            }
        } else {
            mEthdns1 = nullIpInfo;
        }
        log("getEthInfoFromDhcp mEthIpAddress= " + mEthIpAddress);
        log("getEthInfoFromDhcp mEthNetmask= " + mEthNetmask);
        log("getEthInfoFromDhcp mEthGateway= " + mEthGateway);
        log("getEthInfoFromDhcp mEthdns1= " + mEthdns1);
        log("getEthInfoFromDhcp mEthdns2= " + mEthdns2);
    }

    public void getEthInfoFromStaticIp() {
        StaticIpConfiguration staticIpConfiguration = mEthManager.getConfiguration(mIfaceName).getStaticIpConfiguration();

        if (staticIpConfiguration == null) {
            return;
        }
        LinkAddress ipAddress = staticIpConfiguration.getIpAddress();
        InetAddress gateway = staticIpConfiguration.getGateway();
        List<InetAddress> dnsServers = staticIpConfiguration.getDnsServers();


        if (ipAddress != null) {
            mEthIpAddress = ipAddress.getAddress().getHostAddress();
            mEthNetmask = interMask2String(ipAddress.getPrefixLength());
        }
        if (gateway != null) {
            mEthGateway = gateway.getHostAddress();
        }
        mEthdns1 = dnsServers.get(0).getHostAddress();

        if (dnsServers.size() > 1) { /* 只保留两个*/
            mEthdns2 = dnsServers.get(1).getHostAddress();
        }
        log("getEthInfoFromStaticIp mEthIpAddress= " + mEthIpAddress);
        log("getEthInfoFromStaticIp mEthNetmask= " + mEthNetmask);
        log("getEthInfoFromStaticIp mEthGateway= " + mEthGateway);
        log("getEthInfoFromStaticIp mEthdns2= " + mEthdns2);
    }

    /*
     * TODO:
     */
    public void getEthInfo() {
        /*
        mEthHwAddress = mEthManager.getEthernetHwaddr(mEthManager.getEthernetIfaceName());
        if (mEthHwAddress == null) mEthHwAddress = nullIpInfo;
        */
        String way = Settings.System.getString(mContext.getContentResolver() , "test_ip_way");
        IpAssignment mode = way != null&& way.equals("static") ? IpAssignment.STATIC : IpAssignment.DHCP;
        log("IES refreshtestUI way= " + way + " , mode= " + mode);

        IpConfiguration ipConfiguration = mEthManager.getConfiguration(mIfaceName);
        if (ipConfiguration != null) {
            IpAssignment ipAssignment = ipConfiguration.getIpAssignment();
            if (mode != ipAssignment) {
                mode = ipAssignment;
                String ipWay = mode == IpAssignment.STATIC ? "static" : "dhcp";
                Settings.System.putString(mContext.getContentResolver() , "test_ip_way" , ipWay);
                log("IES refreshtestUI change ipWay= " + ipWay + " , mode= " + mode);
            }
        }


        log("getEthInfo mode= " + mode);
        if (mode == IpAssignment.DHCP || mode == IpAssignment.UNASSIGNED) {
            /*
             * getEth from dhcp
             */
            getEthInfoFromDhcp();
        } else if (mode == IpAssignment.STATIC) {
            /*
             * TODO: get static IP
             */
            getEthInfoFromStaticIp();
        }
    }

    /*
     * tools
     */
    private void log(String s) {
        Log.d(TAG, s);
    }

    public static boolean isAvailable() {
        return "true".equals(SystemProperties.get("ro.vendor.ethernet_settings"));
    }
}

四、总结

        至此关于android13以太网的功能介绍完毕,实际上博主认为技术分享应该是无私的,而并非作为牟利的工具,看到很多技术收费的文章,这其实对于自我的成长进步有很大的限制,微薄的利益回报并不值得,博主后续会继续更新对开发有益的文章,愿人人成为大神。

  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驻足观雨听风吟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值