Android 8.1 增加以太网设置功能

       Android 自带EthernetService,默认ip获取方式是动态分配(DHCP),有时候需要手动设置静态IP,但系统没有此项配置,因此我们就自己给它添加一项,将此功能放在了设置应用中。看到有此人要代码,链接在文章最下面,请自行下载

功能所在位置如下图:

涉及到的修改:

 AndroidManifest.xml                                           |  24 ++++
 res/drawable/ic_ethernet.xml                                  |  26 ++++
 res/layout/static_ip_dialog.xml                               | 156 ++++++++++++++++++++++
 res/values-en-rGB/strings.xml                                 |   1 +
 res/values-en-rIN/strings.xml                                 |   1 +
 res/values/arrays.xml                                         |  11 ++
 res/values/strings.xml                                        |  43 +++++++
 res/xml/ethernet_settings.xml                                 |  74 +++++++++++
 res/xml/network_and_internet.xml                              |   8 +-
 src/com/android/settings/ethernet/EtherentStaticIpDialog.java | 281 ++++++++++++++++++++++++++++++++++++++++
 src/com/android/settings/ethernet/EthernetSettings.java       | 616 
 src/com/android/settings/ethernet/getStaticIpInfo.java        |   9 ++

AndroidManifest.xml:

添加 EthernetSettingsActivity

        <activity android:name="Settings$EthernetSettingsActivity"
                android:label="@string/ethernet_settings_title"
                android:icon="@drawable/ic_settings_wireless"
                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.EthernetSettings" />
        </activity>
        
        <!-- Keep compatibility with old shortcuts. -->
         <activity-alias android:name=".EthernetSettings"
                android:label="@string/ethernet_settings"
                android:clearTaskOnLaunch="true"
                android:targetActivity="Settings$EthernetSettingsActivity"
                android:exported="true">
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="com.android.settings.EthernetSettings" />
         </activity-alias>

针对ethernet的配置需要,添加了EthernetSettings.java,EtherentStaticIpDialog.java和getStaticIpInfo.java 三个类。

其它资源文件是一些字符串,图标的添加。更具体的修改及补丁,点击以下链接查看:

基于Settings应用上的patch

这边补充下frameworks的修改:

 core/java/android/net/EthernetManager.java         | 110 +++++++++++++++++++++
 core/java/android/net/IEthernetManager.aidl        |  10 ++
 core/res/AndroidManifest.xml                       |   1 +
 .../com/android/server/ConnectivityService.java    |  14 ++-
 
 4 files changed, 134 insertions(+), 1 deletion(-)
 mode change 100644 => 100755 core/java/android/net/EthernetManager.java
 mode change 100644 => 100755 core/java/android/net/IEthernetManager.aidl

diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java
old mode 100644
new mode 100755
index 31a30968cbc..adfaf08ec91
--- a/core/java/android/net/EthernetManager.java
+++ b/core/java/android/net/EthernetManager.java
@@ -37,6 +37,36 @@ public class EthernetManager {
     private static final String TAG = "EthernetManager";
     private static final int MSG_AVAILABILITY_CHANGED = 1000;
 
+    /**
+     * @hide
+     */
+    public static final String ETHERNET_STATE_CHANGED_ACTION = "android.net.ethernet.ETHERNET_STATE_CHANGED";
+
+    /**
+     * @hide
+     */
+    public static final String EXTRA_ETHERNET_STATE = "ethernet_state";
+
+    /**
+     * @hide
+     */
+    public static final int ETHER_STATE_DISCONNECTED = 0;
+
+    /**
+     * @hide
+     */
+    public static final int ETHER_STATE_CONNECTING = 1;
+
+    /**
+     * @hide
+     */
+    public static final int ETHER_STATE_CONNECTED = 2;
+
+    /**
+     * @hide
+     */
+    public static final int ETHER_STATE_DISCONNECTING = 3;
+    
     private final Context mContext;
     private final IEthernetManager mService;
     private final Handler mHandler = new Handler() {
@@ -116,6 +146,86 @@ public class EthernetManager {
             throw e.rethrowFromSystemServer();
         }
     }
+    
+    public int getEthernetCarrierState(String ifname) {
+        try {
+            return mService.getEthernetCarrierState(ifname);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public String getEthernetMacAddress(String ifname) {
+        try {
+            return mService.getEthernetMacAddress(ifname);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public int getEthernetConnectState() {
+        try {
+            return mService.getEthernetConnectState();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public String getIpAddress() {
+        try {
+            return mService.getIpAddress();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public String getNetmask() {
+        try {
+            return mService.getNetmask();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public String getGateway() {
+        try {
+            return mService.getGateway();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public String getDns() {
+        try {
+            return mService.getDns();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public String dumpCurrentState(int state) {
+        try {
+            return mService.dumpCurrentState(state);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public void reconnect(String iface) {
+        try {
+            mService.reconnect(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public void disconnect(String iface) {
+        try {
+            mService.disconnect(iface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 
     /**
      * Adds a listener.
diff --git a/core/java/android/net/IEthernetManager.aidl b/core/java/android/net/IEthernetManager.aidl
old mode 100644
new mode 100755
index 7a92eb955ac..39d6b1339f8
--- a/core/java/android/net/IEthernetManager.aidl
+++ b/core/java/android/net/IEthernetManager.aidl
@@ -29,6 +29,16 @@ interface IEthernetManager
     IpConfiguration getConfiguration();
     void setConfiguration(in IpConfiguration config);
     boolean isAvailable();
+    int getEthernetCarrierState(String ifname);
+    String getEthernetMacAddress(String ifname);
+    int getEthernetConnectState();
+    String getIpAddress();
+    String getNetmask();
+    String getGateway();
+    String getDns();
+    String dumpCurrentState(int state);
+    void reconnect(String iface);
+    void disconnect(String iface);
     void addListener(in IEthernetServiceListener listener);
     void removeListener(in IEthernetServiceListener listener);
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e77c920165b..2b1eb734d61 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -342,6 +342,7 @@
             android:name="android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED" />
     <protected-broadcast android:name="android.net.scoring.SCORE_NETWORKS" />
     <protected-broadcast android:name="android.net.scoring.SCORER_CHANGED" />
+    <protected-broadcast android:name="android.net.ethernet.ETHERNET_STATE_CHANGED" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE" />
     <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 9afa825a7d3..272f48f1a98 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -195,6 +195,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
     // system property that can override the above value
     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
             "android.telephony.apn-restore";
+            
+    // if true:
+    //    wifi and ethernet can coexist, if wifi and ethernet connect together, prefered to use ethernet
+    // if false:
+    //    wifi and ethernet can't coexist, if wifi and ethernet connect together, will tear down wifi
+    //    TODO: still have bug in this case to fix (like can't reconnect wifi when ethernet disconnect)
+    private static final boolean ENABLE_NETWORK_COEXIST = true;
 
     // How long to wait before putting up a "This network doesn't have an Internet connection,
     // connect anyway?" dialog after the user selects a network that doesn't validate.
@@ -4799,7 +4806,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
                 break;
             }
         }
-        nai.asyncChannel.disconnect();
+        
+        if (ENABLE_NETWORK_COEXIST) {
+             log("Skip teardownUnneededNetwork: " + nai.name());
+        } else {
+             nai.asyncChannel.disconnect();
+        }
     }
 
     private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
-- 
2.16.1

frameworks/opt 相关部分:
 .../server/ethernet/EthernetNetworkFactory.java    | 262 ++++++++++++++++++++-
 .../server/ethernet/EthernetServiceImpl.java       |  70 +++++-
 2 files changed, 325 insertions(+), 7 deletions(-)
 mode change 100644 => 100755 java/com/android/server/ethernet/EthernetNetworkFactory.java
 mode change 100644 => 100755 java/com/android/server/ethernet/EthernetServiceImpl.java

diff --git a/java/com/android/server/ethernet/EthernetNetworkFactory.java b/java/com/android/server/ethernet/EthernetNetworkFactory.java
old mode 100644
new mode 100755
index d6d0def..a05dea0
--- a/java/com/android/server/ethernet/EthernetNetworkFactory.java
+++ b/java/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -34,6 +34,10 @@ import android.net.NetworkInfo.DetailedState;
 import android.net.StaticIpConfiguration;
 import android.net.ip.IpManager;
 import android.net.ip.IpManager.ProvisioningConfiguration;
+import android.net.RouteInfo;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
@@ -43,6 +47,22 @@ import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.content.Intent;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import java.io.FileDescriptor;
+import java.io.File;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.Exception;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
 
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.net.BaseNetworkObserver;
@@ -102,12 +122,54 @@ class EthernetNetworkFactory {
 
     /** Data members. All accesses to these must be on the handler thread. */
     private String mIface = "";
+    private static String mIfaceTmp = "";
     private String mHwAddr;
     private boolean mLinkUp;
     private NetworkInfo mNetworkInfo;
     private LinkProperties mLinkProperties;
     private IpManager mIpManager;
     private boolean mNetworkRequested = false;
+    public int mEthernetCurrentState = EthernetManager.ETHER_STATE_DISCONNECTED;
+    private boolean mReconnecting;
+    private IpAssignment mConnectMode;
+    
+    public String dumpEthCurrentState(int curState) {
+        if (curState == EthernetManager.ETHER_STATE_DISCONNECTED)
+            return "DISCONNECTED";
+        else if (curState == EthernetManager.ETHER_STATE_CONNECTING)
+            return "CONNECTING";
+        else if (curState == EthernetManager.ETHER_STATE_CONNECTED)
+            return "CONNECTED";
+        else if (curState == EthernetManager.ETHER_STATE_DISCONNECTING)
+            return "DISCONNECTING";
+        return "DISCONNECTED";
+    }
+
+    private void sendEthernetStateChangedBroadcast(int curState) {
+        if (mEthernetCurrentState == curState)
+            return;
+        Log.d(TAG, "sendEthernetStateChangedBroadcast: curState = " + dumpEthCurrentState(curState));
+        mEthernetCurrentState = curState;
+        final Intent intent = new Intent(EthernetManager.ETHERNET_STATE_CHANGED_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        intent.putExtra(EthernetManager.EXTRA_ETHERNET_STATE, curState);
+        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
+    private String ReadFromFile(File file) {
+        if((file != null) && file.exists()) {
+            try {
+                FileInputStream fin= new FileInputStream(file);
+                BufferedReader reader= new BufferedReader(new InputStreamReader(fin));
+                String flag = reader.readLine();
+                fin.close();
+                return flag;
+            } catch(Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
 
     EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) {
         initNetworkCapabilities();
@@ -165,15 +227,55 @@ class EthernetNetworkFactory {
         if (!mIface.equals(iface)) {
             return;
         }
-        Log.d(TAG, "updateInterface: " + iface + " link " + (up ? "up" : "down"));
+        
+        if (!mReconnecting)
+            Log.d(TAG, "updateInterface: " + iface + " link " + (up ? "up" : "down"));
+    
+        if (up && mEthernetCurrentState != EthernetManager.ETHER_STATE_DISCONNECTED) {
+            Log.d(TAG, "Already connected or connecting, skip connect");
+            return;
+        }
 
         mLinkUp = up;
         if (up) {
             maybeStartIpManager();
         } else {
+            sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_DISCONNECTING);
             stopIpManager();
         }
     }
+    
+        // first disconnect, then connect
+    public void reconnect(String iface) {
+        Log.d(TAG, "reconnect:");
+        mReconnecting = true;
+
+        if (iface == null)
+            iface = mIface;
+
+        Log.d(TAG, "first disconnect");
+        updateInterfaceState(iface, false);
+
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException ignore) {
+        }
+
+        Log.d(TAG, "then connect");
+        updateInterfaceState(iface, true);
+        mReconnecting = false;
+    }
+
+    public void disconnect(String iface) {
+        Log.d(TAG, "disconnect:");
+        mReconnecting = true;
+
+        if (iface == null)
+            iface = mIface;
+
+        updateInterfaceState(iface, false);
+        mReconnecting = false;
+    }
 
     private class InterfaceObserver extends BaseNetworkObserver {
         @Override
@@ -185,6 +287,7 @@ class EthernetNetworkFactory {
 
         @Override
         public void interfaceAdded(String iface) {
+            Log.d(TAG, "interfaceAdded: " + iface);
             mHandler.post(() -> {
                 maybeTrackInterface(iface);
             });
@@ -192,6 +295,7 @@ class EthernetNetworkFactory {
 
         @Override
         public void interfaceRemoved(String iface) {
+            Log.d(TAG, "interfaceRemoved: " + iface);
             mHandler.post(() -> {
                 if (stopTrackingInterface(iface)) {
                     trackFirstAvailableInterface();
@@ -202,6 +306,7 @@ class EthernetNetworkFactory {
 
     private void setInterfaceUp(String iface) {
         // Bring up the interface so we get link status indications.
+        Log.d(TAG, "setInterfaceUp: " + iface);
         try {
             mNMService.setInterfaceUp(iface);
             String hwAddr = null;
@@ -245,6 +350,7 @@ class EthernetNetworkFactory {
         Log.d(TAG, "Stopped tracking interface " + iface);
         setInterfaceInfo("", null);
         stopIpManager();
+        sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_DISCONNECTED);
         return true;
     }
 
@@ -288,16 +394,20 @@ class EthernetNetworkFactory {
             stopIpManager();
             return;
         }
+        Log.d(TAG, "IP success: lp = " + linkProperties);
         mLinkProperties = linkProperties;
         mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);
+        sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_CONNECTED);
 
         // Create our NetworkAgent.
         mNetworkAgent = new NetworkAgent(mHandler.getLooper(), mContext,
                 NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
                 NETWORK_SCORE) {
             public void unwanted() {
+                Log.d(TAG, "unwanted");
                 if (this == mNetworkAgent) {
                     stopIpManager();
+                    sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_DISCONNECTED);
                 } else if (mNetworkAgent != null) {
                     Log.d(TAG, "Ignoring unwanted as we have a more modern " +
                             "instance");
@@ -331,32 +441,47 @@ class EthernetNetworkFactory {
             Log.d(TAG, String.format("starting IpManager(%s): mNetworkInfo=%s", mIface,
                     mNetworkInfo));
         }
+        
+        int carrier = getEthernetCarrierState(mIface);
+        Log.d(TAG, "startIpManager: " + mIface + " carrier = " + carrier);
+        if (carrier != 1) {
+            return;
+        }
 
         LinkProperties linkProperties;
 
         IpConfiguration config = mEthernetManager.getConfiguration();
+        mConnectMode = config.getIpAssignment();
 
+        sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_CONNECTING);
         if (config.getIpAssignment() == IpAssignment.STATIC) {
+            Log.d(TAG, "config STATIC");
             if (!setStaticIpAddress(config.getStaticIpConfiguration())) {
                 // We've already logged an error.
+                sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_DISCONNECTED);
                 return;
             }
             linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);
+            mHandler.post(() -> onIpLayerStarted(linkProperties));
         } else {
+            Log.d(TAG, "config DHCP");
             mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
             IpManager.Callback ipmCallback = new IpManager.Callback() {
                 @Override
                 public void onProvisioningSuccess(LinkProperties newLp) {
+                    Log.d(TAG, "onProvisioningSuccess: lp = " + newLp);
                     mHandler.post(() -> onIpLayerStarted(newLp));
                 }
 
                 @Override
                 public void onProvisioningFailure(LinkProperties newLp) {
+                    Log.d(TAG, "onProvisioningFailure: lp = " + newLp);
                     mHandler.post(() -> onIpLayerStopped(newLp));
                 }
 
                 @Override
                 public void onLinkPropertiesChange(LinkProperties newLp) {
+                    Log.d(TAG, "onLinkPropertiesChange: lp = " + newLp);
                     mHandler.post(() -> updateLinkProperties(newLp));
                 }
             };
@@ -397,6 +522,7 @@ class EthernetNetworkFactory {
         // Interface match regex.
         mIfaceMatch = context.getResources().getString(
                 com.android.internal.R.string.config_ethernet_iface_regex);
+        Log.d(TAG, "EthernetNetworkFactory start " + mIfaceMatch);
 
         // Create and register our NetworkFactory.
         mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, mHandler.getLooper());
@@ -405,6 +531,8 @@ class EthernetNetworkFactory {
         mFactory.register();
 
         mContext = context;
+        mReconnecting = false;
+        mConnectMode = IpAssignment.DHCP;
 
         // Start tracking interface change events.
         mInterfaceObserver = new InterfaceObserver();
@@ -428,9 +556,23 @@ class EthernetNetworkFactory {
                     // Note: if the interface already has link (e.g., if we crashed and got
                     // restarted while it was running), we need to fake a link up notification so we
                     // start configuring it.
-                    if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {
-                        updateInterfaceState(iface, true);
-                    }
+                    //if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {
+                    mIfaceTmp = iface;
+                    new Thread(new Runnable() {
+                        public void run() {
+                            // carrier is always 1 when kernel boot up no matter RJ45 plugin or not, 
+                            // sleep a little time to wait kernel's correct carrier status
+                            try {
+                                Thread.sleep(3000);
+                            } catch (InterruptedException ignore) {
+                            }
+                            int carrier = getEthernetCarrierState(mIfaceTmp);
+                            Log.d(TAG, mIfaceTmp + " carrier = " + carrier);
+                            if (carrier == 1) {
+                                updateInterfaceState(mIfaceTmp, true);
+                            }
+                        }
+                    }).start();
                     break;
                 }
             }
@@ -440,9 +582,11 @@ class EthernetNetworkFactory {
     }
 
     public void stop() {
+        Log.d(TAG, "EthernetNetworkFactory stop");
         stopIpManager();
         setInterfaceInfo("", null);
         mFactory.unregister();
+        sendEthernetStateChangedBroadcast(EthernetManager.ETHER_STATE_DISCONNECTED);
     }
 
     private void initNetworkCapabilities() {
@@ -458,6 +602,113 @@ class EthernetNetworkFactory {
     public boolean isTrackingInterface() {
         return !TextUtils.isEmpty(mIface);
     }
+    public int getEthernetCarrierState(String ifname) {
+        if(ifname != "") {
+            try {
+                File file = new File("/sys/class/net/" + ifname + "/carrier");
+                String carrier = ReadFromFile(file);
+                return Integer.parseInt(carrier);
+            } catch(Exception e) {
+                e.printStackTrace();
+                return 0;
+            }
+        } else {
+            return 0;
+        }
+    }
+    
+        public String getEthernetMacAddress(String ifname) {
+        if(ifname != "") {
+            try {
+                File file = new File("/sys/class/net/" + ifname + "/address");
+                String address = ReadFromFile(file);
+                return address;
+            } catch(Exception e) {
+                e.printStackTrace();
+                return "";
+            }
+        } else {
+            return "";
+        }
+    }
+
+    public String getIpAddress() {
+        IpConfiguration config = mEthernetManager.getConfiguration();
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            return config.getStaticIpConfiguration().ipAddress.getAddress().getHostAddress();
+        } else {
+            for (LinkAddress l : 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();
+    	   }
+    }
+
+    public String getNetmask() {
+        IpConfiguration config = mEthernetManager.getConfiguration();
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            return prefix2netmask(config.getStaticIpConfiguration().ipAddress.getPrefixLength());
+        } else {
+            for (LinkAddress l : mLinkProperties.getLinkAddresses()) {
+                InetAddress source = l.getAddress();
+                if (source instanceof Inet4Address) {
+                    return prefix2netmask(l.getPrefixLength());
+                }
+            }
+        }
+        return "";
+    }
+	
+    public String getGateway() {
+        IpConfiguration config = mEthernetManager.getConfiguration();
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            return config.getStaticIpConfiguration().gateway.getHostAddress();
+        } else {
+            for (RouteInfo route : 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"
+     */
+    public String getDns() {
+        String dns = "";
+        IpConfiguration config = mEthernetManager.getConfiguration();
+        if (config.getIpAssignment() == IpAssignment.STATIC) {
+            for (InetAddress nameserver : config.getStaticIpConfiguration().dnsServers) {
+                dns += nameserver.getHostAddress() + ",";
+            }			
+        } else {		
+            for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
+                dns += nameserver.getHostAddress() + ",";
+            }
+        }
+        return dns;		
+    }
+
 
     /**
      * Set interface information and notify listeners if availability is changed.
@@ -510,6 +761,9 @@ class EthernetNetworkFactory {
                 } else {
                     pw.println("Not tracking any interface");
                 }
+                
+                pw.println();
+                pw.println("mEthernetCurrentState: " + dumpEthCurrentState(mEthernetCurrentState));
 
                 pw.println();
                 pw.println("NetworkInfo: " + mNetworkInfo);
diff --git a/java/com/android/server/ethernet/EthernetServiceImpl.java b/java/com/android/server/ethernet/EthernetServiceImpl.java
old mode 100644
new mode 100755
index 42996d6..2034f24
--- a/java/com/android/server/ethernet/EthernetServiceImpl.java
+++ b/java/com/android/server/ethernet/EthernetServiceImpl.java
@@ -121,10 +121,14 @@ 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.
-            if (!config.equals(mIpConfiguration)) {
+            if (true/*!config.equals(mIpConfiguration)*/) {
                 mIpConfiguration = new IpConfiguration(config);
-                mTracker.stop();
-                mTracker.start(mContext, mHandler);
+                if (false) { // old android original method
+                   mTracker.stop();
+                   mTracker.start(mContext, mHandler);
+                } else { // new method
+                    mTracker.reconnect("eth0");
+                }
             }
         }
     }
@@ -162,6 +166,66 @@ public class EthernetServiceImpl extends IEthernetManager.Stub {
         enforceAccessPermission();
         mListeners.unregister(listener);
     }
+    
+    @Override
+    public int getEthernetCarrierState(String ifname) {
+        enforceAccessPermission();
+        return mTracker.getEthernetCarrierState(ifname);
+    }
+
+    @Override
+    public String getEthernetMacAddress(String ifname) {
+        enforceAccessPermission();
+        return mTracker.getEthernetMacAddress(ifname);
+    }
+
+    @Override
+    public int getEthernetConnectState() {
+        enforceAccessPermission();
+        return mTracker.mEthernetCurrentState;
+    }
+
+    @Override
+    public String getIpAddress() {
+        enforceAccessPermission();
+        return mTracker.getIpAddress();
+    }
+
+    @Override
+    public String getNetmask() {
+        enforceAccessPermission();
+        return mTracker.getNetmask();
+    }
+
+    @Override
+    public String getGateway() {
+        enforceAccessPermission();
+        return mTracker.getGateway();
+    }
+
+    @Override
+    public String getDns() {
+        enforceAccessPermission();
+        return mTracker.getDns();
+    }
+
+    @Override
+    public String dumpCurrentState(int state) {
+        enforceAccessPermission();
+        return mTracker.dumpEthCurrentState(state);
+    }
+
+    @Override
+    public void reconnect(String iface) {
+        enforceAccessPermission();
+        mTracker.reconnect(iface);
+    }
+
+    @Override
+    public void disconnect(String iface) {
+        enforceAccessPermission();
+        mTracker.disconnect(iface);
+    }
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-- 
2.16.1

 

  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
Android 8.1引入了一些新功能,其中一个是试图打通与Chromebook的联系。这个新功能被称为SMS Connect Prebuilt,它允许用户在Chromebook上收发手机短信,并接收新短信的通知提醒。这样用户可以更方便地在Chromebook上处理手机短信。\[2\] 另外,Android 8.1还引入了一个有趣的功能,即允许动态壁纸为系统UI提供颜色信息。开发者可以通过创建WallpaperColors对象来实现这一功能,从而为系统UI提供更加丰富的颜色体验。\[3\] 总的来说,Android 8.1的新功能使用户能够更好地与Chromebook进行交互,并且提供了更丰富的颜色体验。 #### 引用[.reference_title] - *1* *2* [Android 8.1功能怎么样?Android 8.1功能介绍](https://blog.csdn.net/weixin_35106801/article/details/117474348)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Android 8.1 功能与新特性](https://blog.csdn.net/wjky2014/article/details/100938867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值