Andorid: msm8909: add Ethernet function

Written in front

SOC: Qualcomm msm8909

Core-Board: SC20-CE QA/PJ

Base-Board: xxx

Linux Kernel: xxx

Android: 7.1

 

This purpose

Add Ethernet function to Android system, find Ethernet option in system setting menu, complete Ethernet function setting, and prompt Ethernet network status in system status bar.

 

Detailed steps

 

Modification of device

Modify file:

device\qcom\common\rootdir\etc\init.qcom.rc

Add the following:

service dhcpcd_eth0 /system/bin/dhcpcd -ABDKL
    class main
    disabled
    oneshot

service iprenew_eth0 /system/bin/dhcpcd -n
    class late_start
    disabled
    oneshot

Modify file:

device/qcom/msm8909/msm8909.mk

Add the following to "product \ copy \ files" and note that the end "\" should not be missed after the previous value:

    frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml

After the modification, it looks like this:

# Feature definition files for msm8953
PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.sensor.accelerometer.xml:system/etc/permissions/android.hardware.sensor.accelerometer.xml \
    frameworks/native/data/etc/android.hardware.sensor.compass.xml:system/etc/permissions/android.hardware.sensor.compass.xml \
    frameworks/native/data/etc/android.hardware.sensor.gyroscope.xml:system/etc/permissions/android.hardware.sensor.gyroscope.xml \
    frameworks/native/data/etc/android.hardware.sensor.light.xml:system/etc/permissions/android.hardware.sensor.light.xml \
    frameworks/native/data/etc/android.hardware.sensor.proximity.xml:system/etc/permissions/android.hardware.sensor.proximity.xml \
    frameworks/native/data/etc/android.hardware.sensor.barometer.xml:system/etc/permissions/android.hardware.sensor.barometer.xml \
    frameworks/native/data/etc/android.hardware.sensor.stepcounter.xml:system/etc/permissions/android.hardware.sensor.stepcounter.xml \
    frameworks/native/data/etc/android.hardware.sensor.stepdetector.xml:system/etc/permissions/android.hardware.sensor.stepdetector.xml \
    frameworks/native/data/etc/android.hardware.ethernet.xml:system/etc/permissions/android.hardware.ethernet.xml

Modify the document:

device/qcom/common/device/overlay/frameworks/base/core/res/res/values/config.xml

Add the following:

       <item><xliff:g id="id">ethernet</xliff:g></item>

After modification, it looks like this:

    <!-- Do not translate. Defines the slots for the right-hand side icons.  That is to say, the
         icons in the status bar that are not notifications. -->
    <string-array name="config_statusBarIcons">
       <item><xliff:g id="id">managed_profile</xliff:g></item>
       <item><xliff:g id="id">ime</xliff:g></item>
       <item><xliff:g id="id">sync_failing</xliff:g></item>
       <item><xliff:g id="id">sync_active</xliff:g></item>
       <item><xliff:g id="id">cast</xliff:g></item>
       <item><xliff:g id="id">hotspot</xliff:g></item>
       <item><xliff:g id="id">location</xliff:g></item>
       <item><xliff:g id="id">bluetooth</xliff:g></item>
       <item><xliff:g id="id">nfc</xliff:g></item>
       <item><xliff:g id="id">femtoicon</xliff:g></item>
       <item><xliff:g id="id">tty</xliff:g></item>
       <item><xliff:g id="id">speakerphone</xliff:g></item>
       <item><xliff:g id="id">zen</xliff:g></item>
       <item><xliff:g id="id">mute</xliff:g></item>
       <item><xliff:g id="id">volume</xliff:g></item>
       <item><xliff:g id="id">wifi</xliff:g></item>
       <item><xliff:g id="id">ethernet</xliff:g></item>
       <item><xliff:g id="id">cdma_eri</xliff:g></item>
       <item><xliff:g id="id">data_connection</xliff:g></item>
       <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
       <item><xliff:g id="id">phone_signal</xliff:g></item>
       <item><xliff:g id="id">battery</xliff:g></item>
       <item><xliff:g id="id">alarm_clock</xliff:g></item>
       <item><xliff:g id="id">secure</xliff:g></item>
       <item><xliff:g id="id">clock</xliff:g></item>
    </string-array>

 

Modification of frameworks

Modify file:

frameworks/base/core/java/android/net/EthernetManager.java

Add the following:

    public static final int ETH_STATE_UNKNOWN = 0;  //law
	public static final int ETH_STATE_DISABLED = 1;
	public static final int ETH_STATE_ENABLED = 2;
  
	public void start() {
	    try {
	        mService.Trackstart();
	    } catch (NullPointerException | RemoteException e) {

	    }  
	}  
  
	public void stop() {
  	  try {
 	       mService.Trackstop();
 	   } catch (NullPointerException | RemoteException e) {
 	   }
	}

Modify file:

frameworks\base\core\java\android\net\IEthernetManager.aidl

Add the following:

    void Trackstart();//add by law
    void Trackstop();

Modify file:

 frameworks\base\core\java\android\provider\Settings.java.

Add the following:

		
		/**
		 * law add
		 * {@hide}
		 */
		public static final String ETHERNET_ON = "ethernet_on";//add by law

Modify file:

frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java


Add the following dependencies:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

Add Handler property in this class:

    private Handler mHandler;

Add a status flag and create a broadcast reception:

	private boolean isStatusBarReady= false;


	private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
	    @Override
	    public void onReceive(Context context, Intent intent) {
	        String action = intent.getAction();
	        Log.d(TAG, "klein----BroadcastReceiver--action = " + action);
	        if (action.equals(Intent.ACTION_ETHERNET_STATUSBAR_READY)) {
	            isStatusBarReady = true;
	            Log.d(TAG,"statusbar is ready, update current status");
	            if (mLinkUp){
	                Log.d(TAG,"updateAgent connected");
	                Intent intent1 = new Intent();
	                intent1.setAction(Intent.ACTION_ETHERNET_CONNECTED);
	                mContext.sendBroadcast(intent1);
	            }else{
	                Log.d(TAG,"updateAgent disconnected");
	                Intent intent2 = new Intent();
	                intent2.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
	                mContext.sendBroadcast(intent2);
	            }
	        }
	    }
	};

Add the update state logic to the updateInterfaceState method:

        if (up){
            Log.d(TAG,"updateAgent connected");
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_ETHERNET_CONNECTED);
            mContext.sendBroadcast(intent);
        }else{
            Log.d(TAG,"updateAgent disconnected");
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
            mContext.sendBroadcast(intent);
        }

In the "onRequestNetwork" method, add judgment when the "ipProvisioningThread" thread is initialized:

                          //if error then stop and restart add by law
                          if((mContext != null) && (mHandler != null)) {
                              Log.d(TAG, "Setting static ip failed now restart");
                              stop();
                              start(mContext,mHandler);
                           }  

Add the following to the start method:

        mHandler = target;//add by law
                            if(!iface.equals("eth0"))//add by hclydao make sure the interface is eth0
                                continue;
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_ETHERNET_STATUSBAR_READY);
        mContext.registerReceiver(mIntentReceiver, filter);
        Log.d(TAG, "klein----EthernetNetworkFactory start");

The complete documents are as follows:

/*
 * 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 com.android.server.ethernet;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DhcpResults;
import android.net.EthernetManager;
import android.net.IEthernetServiceListener;
import android.net.InterfaceConfiguration;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.LinkProperties;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.StaticIpConfiguration;
import android.net.ip.IpManager;
import android.net.ip.IpManager.ProvisioningConfiguration;
import android.net.ip.IpManager.WaitForProvisioningCallback;
import android.os.Handler;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.util.IndentingPrintWriter;
import com.android.server.net.BaseNetworkObserver;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;


/**
 * Manages connectivity for an Ethernet interface.
 *
 * Ethernet Interfaces may be present at boot time or appear after boot (e.g.,
 * for Ethernet adapters connected over USB). This class currently supports
 * only one interface. When an interface appears on the system (or is present
 * at boot time) this class will start tracking it and bring it up, and will
 * attempt to connect when requested. Any other interfaces that subsequently
 * appear will be ignored until the tracked interface disappears. Only
 * interfaces whose names match the <code>config_ethernet_iface_regex</code>
 * regular expression are tracked.
 *
 * This class reports a static network score of 70 when it is tracking an
 * interface and that interface's link is up, and a score of 0 otherwise.
 *
 * @hide
 */
class EthernetNetworkFactory {
    private static final String NETWORK_TYPE = "Ethernet";
    private static final String TAG = "EthernetNetworkFactory";
    private static final int NETWORK_SCORE = 70;
    private static final boolean DBG = true;
    private Handler mHandler;

    /** Tracks interface changes. Called from NetworkManagementService. */
    private InterfaceObserver mInterfaceObserver;

    /** For static IP configuration */
    private EthernetManager mEthernetManager;

    /** To set link state and configure IP addresses. */
    private INetworkManagementService mNMService;

    /* To communicate with ConnectivityManager */
    private NetworkCapabilities mNetworkCapabilities;
    private NetworkAgent mNetworkAgent;
    private LocalNetworkFactory mFactory;
    private Context mContext;

    /** Product-dependent regular expression of interface names we track. */
    private static String mIfaceMatch = "";

    /** To notify Ethernet status. */
    private final RemoteCallbackList<IEthernetServiceListener> mListeners;

    /** Data members. All accesses to these must be synchronized(this). */
    private static String mIface = "";
    private String mHwAddr;
    private static boolean mLinkUp;
    private NetworkInfo mNetworkInfo;
    private LinkProperties mLinkProperties;
    private IpManager mIpManager;
    private Thread mIpProvisioningThread;
	private boolean isStatusBarReady= false;


	private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
	    @Override
	    public void onReceive(Context context, Intent intent) {
	        String action = intent.getAction();
	        Log.d(TAG, "klein----BroadcastReceiver--action = " + action);
	        if (action.equals(Intent.ACTION_ETHERNET_STATUSBAR_READY)) {
	            isStatusBarReady = true;
	            Log.d(TAG,"statusbar is ready, update current status");
	            if (mLinkUp){
	                Log.d(TAG,"updateAgent connected");
	                Intent intent1 = new Intent();
	                intent1.setAction(Intent.ACTION_ETHERNET_CONNECTED);
	                mContext.sendBroadcast(intent1);
	            }else{
	                Log.d(TAG,"updateAgent disconnected");
	                Intent intent2 = new Intent();
	                intent2.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
	                mContext.sendBroadcast(intent2);
	            }
	        }
	    }
	};


    EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) {
        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
        mLinkProperties = new LinkProperties();
        initNetworkCapabilities();
        mListeners = listeners;
    }

    private class LocalNetworkFactory extends NetworkFactory {
        LocalNetworkFactory(String name, Context context, Looper looper) {
            super(looper, context, name, new NetworkCapabilities());
        }

        protected void startNetwork() {
            onRequestNetwork();
        }
        protected void stopNetwork() {
        }
    }

    private void stopIpManagerLocked() {
        if (mIpManager != null) {
            mIpManager.shutdown();
            mIpManager = null;
        }
    }

    private void stopIpProvisioningThreadLocked() {
        stopIpManagerLocked();

        if (mIpProvisioningThread != null) {
            mIpProvisioningThread.interrupt();
            mIpProvisioningThread = null;
        }
    }

    /**
     * Updates interface state variables.
     * Called on link state changes or on startup.
     */
    private void updateInterfaceState(String iface, boolean up) {
        if (!mIface.equals(iface)) {
            return;
        }
        Log.d(TAG, "updateInterface: " + iface + " link " + (up ? "up" : "down"));

        if (up){
            Log.d(TAG,"updateAgent connected");
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_ETHERNET_CONNECTED);
            mContext.sendBroadcast(intent);
        }else{
            Log.d(TAG,"updateAgent disconnected");
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_ETHERNET_DISCONNECTED);
            mContext.sendBroadcast(intent);
        }

        synchronized(this) {
            mLinkUp = up;
            mNetworkInfo.setIsAvailable(up);
            if (!up) {
                // Tell the agent we're disconnected. It will call disconnect().
                mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
                stopIpProvisioningThreadLocked();
            }
            updateAgent();
            // set our score lower than any network could go
            // so we get dropped.  TODO - just unregister the factory
            // when link goes down.
            mFactory.setScoreFilter(up ? NETWORK_SCORE : -1);
        }
    }

    private class InterfaceObserver extends BaseNetworkObserver {
        @Override
        public void interfaceLinkStateChanged(String iface, boolean up) {
            updateInterfaceState(iface, up);
        }

        @Override
        public void interfaceAdded(String iface) {
            maybeTrackInterface(iface);
        }

        @Override
        public void interfaceRemoved(String iface) {
            stopTrackingInterface(iface);
        }
    }

    private void setInterfaceUp(String iface) {
        // Bring up the interface so we get link status indications.
        try {
            mNMService.setInterfaceUp(iface);
            String hwAddr = null;
            InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);

            if (config == null) {
                Log.e(TAG, "Null iterface config for " + iface + ". Bailing out.");
                return;
            }

            synchronized (this) {
                if (!isTrackingInterface()) {
                    setInterfaceInfoLocked(iface, config.getHardwareAddress());
                    mNetworkInfo.setIsAvailable(true);
                    mNetworkInfo.setExtraInfo(mHwAddr);
                } else {
                    Log.e(TAG, "Interface unexpectedly changed from " + iface + " to " + mIface);
                    mNMService.setInterfaceDown(iface);
                }
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Error upping interface " + mIface + ": " + e);
        }
    }

    private boolean maybeTrackInterface(String iface) {
        // If we don't already have an interface, and if this interface matches
        // our regex, start tracking it.
        if (!iface.matches(mIfaceMatch) || isTrackingInterface())
            return false;

        Log.d(TAG, "Started tracking interface " + iface);
        setInterfaceUp(iface);
        return true;
    }

    private void stopTrackingInterface(String iface) {
        if (!iface.equals(mIface))
            return;

        Log.d(TAG, "Stopped tracking interface " + iface);
        // TODO: Unify this codepath with stop().
        synchronized (this) {
            stopIpProvisioningThreadLocked();
            setInterfaceInfoLocked("", null);
            mNetworkInfo.setExtraInfo(null);
            mLinkUp = false;
            mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
            updateAgent();
            mNetworkAgent = null;
            mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
            mLinkProperties = new LinkProperties();
        }
    }

    private boolean setStaticIpAddress(StaticIpConfiguration staticConfig) {
        if (staticConfig.ipAddress != null &&
                staticConfig.gateway != null &&
                staticConfig.dnsServers.size() > 0) {
            try {
                Log.i(TAG, "Applying static IPv4 configuration to " + mIface + ": " + staticConfig);
                InterfaceConfiguration config = mNMService.getInterfaceConfig(mIface);
                config.setLinkAddress(staticConfig.ipAddress);
                mNMService.setInterfaceConfig(mIface, config);
                return true;
            } catch(RemoteException|IllegalStateException e) {
               Log.e(TAG, "Setting static IP address failed: " + e.getMessage());
            }
        } else {
            Log.e(TAG, "Invalid static IP configuration.");
        }
        return false;
    }

    public void updateAgent() {
        synchronized (EthernetNetworkFactory.this) {
            if (mNetworkAgent == null) return;
            if (DBG) {
                Log.i(TAG, "Updating mNetworkAgent with: " +
                      mNetworkCapabilities + ", " +
                      mNetworkInfo + ", " +
                      mLinkProperties);
            }
            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
            mNetworkAgent.sendLinkProperties(mLinkProperties);
            // never set the network score below 0.
            mNetworkAgent.sendNetworkScore(mLinkUp? NETWORK_SCORE : 0);
        }
    }

    /* Called by the NetworkFactory on the handler thread. */
    public void onRequestNetwork() {
        synchronized(EthernetNetworkFactory.this) {
            if (mIpProvisioningThread != null) {
                return;
            }
        }

        final Thread ipProvisioningThread = new Thread(new Runnable() {
            public void run() {
                if (DBG) {
                    Log.d(TAG, String.format("starting ipProvisioningThread(%s): mNetworkInfo=%s",
                            mIface, mNetworkInfo));
                }

                LinkProperties linkProperties;

                IpConfiguration config = mEthernetManager.getConfiguration();

                if (config.getIpAssignment() == IpAssignment.STATIC) {
                    if (!setStaticIpAddress(config.getStaticIpConfiguration())) {
                          //if error then stop and restart add by law
                          if((mContext != null) && (mHandler != null)) {
                              Log.d(TAG, "Setting static ip failed now restart");
                              stop();
                              start(mContext,mHandler);
                           }  
                        // We've already logged an error.
                        return;
                    }
                    linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);
                } else {
                    mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
                    WaitForProvisioningCallback ipmCallback = new WaitForProvisioningCallback() {
                        @Override
                        public void onLinkPropertiesChange(LinkProperties newLp) {
                            synchronized(EthernetNetworkFactory.this) {
                                if (mNetworkAgent != null && mNetworkInfo.isConnected()) {
                                    mLinkProperties = newLp;
                                    mNetworkAgent.sendLinkProperties(newLp);
                                }
                            }
                        }
                    };

                    synchronized(EthernetNetworkFactory.this) {
                        stopIpManagerLocked();
                        mIpManager = new IpManager(mContext, mIface, ipmCallback);

                        if (config.getProxySettings() == ProxySettings.STATIC ||
                                config.getProxySettings() == ProxySettings.PAC) {
                            mIpManager.setHttpProxy(config.getHttpProxy());
                        }

                        final String tcpBufferSizes = mContext.getResources().getString(
                                com.android.internal.R.string.config_ethernet_tcp_buffers);
                        if (!TextUtils.isEmpty(tcpBufferSizes)) {
                            mIpManager.setTcpBufferSizes(tcpBufferSizes);
                        }

                        final ProvisioningConfiguration provisioningConfiguration =
                                mIpManager.buildProvisioningConfiguration()
                                        .withProvisioningTimeoutMs(0)
                                        .build();
                        mIpManager.startProvisioning(provisioningConfiguration);
                    }

                    linkProperties = ipmCallback.waitForProvisioning();
                    if (linkProperties == null) {
                        Log.e(TAG, "IP provisioning error");
                        // set our score lower than any network could go
                        // so we get dropped.
                        mFactory.setScoreFilter(-1);
                        synchronized(EthernetNetworkFactory.this) {
                            stopIpManagerLocked();
                        }
                        return;
                    }
                }

                synchronized(EthernetNetworkFactory.this) {
                    if (mNetworkAgent != null) {
                        Log.e(TAG, "Already have a NetworkAgent - aborting new request");
                        stopIpManagerLocked();
                        mIpProvisioningThread = null;
                        return;
                    }
                    mLinkProperties = linkProperties;
                    mNetworkInfo.setIsAvailable(true);
                    mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, mHwAddr);

                    // Create our NetworkAgent.
                    mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext,
                            NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties,
                            NETWORK_SCORE) {
                        public void unwanted() {
                            synchronized(EthernetNetworkFactory.this) {
                                if (this == mNetworkAgent) {
                                    stopIpManagerLocked();

                                    mLinkProperties.clear();
                                    mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,
                                            mHwAddr);
                                    updateAgent();
                                    mNetworkAgent = null;
                                    try {
                                        mNMService.clearInterfaceAddresses(mIface);
                                    } catch (Exception e) {
                                        Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
                                    }
                                } else {
                                    Log.d(TAG, "Ignoring unwanted as we have a more modern " +
                                            "instance");
                                }
                            }
                        };
                    };

                    mIpProvisioningThread = null;
                }

                if (DBG) {
                    Log.d(TAG, String.format("exiting ipProvisioningThread(%s): mNetworkInfo=%s",
                            mIface, mNetworkInfo));
                }
            }
        });

        synchronized(EthernetNetworkFactory.this) {
            if (mIpProvisioningThread == null) {
                mIpProvisioningThread = ipProvisioningThread;
                mIpProvisioningThread.start();
            }
        }
    }

    /**
     * Begin monitoring connectivity
     */
    public synchronized void start(Context context, Handler target) {
        // The services we use.
        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        mNMService = INetworkManagementService.Stub.asInterface(b);
        mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);

        // Interface match regex.
        mIfaceMatch = context.getResources().getString(
                com.android.internal.R.string.config_ethernet_iface_regex);

        // Create and register our NetworkFactory.
        mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper());
        mFactory.setCapabilityFilter(mNetworkCapabilities);
        mFactory.setScoreFilter(-1); // this set high when we have an iface
        mFactory.register();

        mContext = context;
        mHandler = target;//add by law
        // Start tracking interface change events.
        mInterfaceObserver = new InterfaceObserver();
        try {
            mNMService.registerObserver(mInterfaceObserver);
        } catch (RemoteException e) {
            Log.e(TAG, "Could not register InterfaceObserver " + e);
        }

        // If an Ethernet interface is already connected, start tracking that.
        // Otherwise, the first Ethernet interface to appear will be tracked.
        try {
            final String[] ifaces = mNMService.listInterfaces();
            for (String iface : ifaces) {
                synchronized(this) {
                    if (maybeTrackInterface(iface)) {
                        // We have our interface. Track it.
                        // 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. Since we're already holding the lock,
                        // any real link up/down notification will only arrive
                        // after we've done this.
                        if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {
                            if(!iface.equals("eth0"))//add by hclydao make sure the interface is eth0
                                continue;
                            updateInterfaceState(iface, true);
                        }
                        break;
                    }
                }
            }
        } catch (RemoteException|IllegalStateException e) {
            Log.e(TAG, "Could not get list of interfaces " + e);
        }

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_ETHERNET_STATUSBAR_READY);
        mContext.registerReceiver(mIntentReceiver, filter);
        Log.d(TAG, "klein----EthernetNetworkFactory start");
    }

    public synchronized void stop() {
        stopIpProvisioningThreadLocked();
        // ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object
        // with a state of DISCONNECTED or SUSPENDED. So we can't simply clear our NetworkInfo here:
        // that sets the state to IDLE, and ConnectivityService will still think we're connected.
        //
        // TODO: stop using explicit comparisons to DISCONNECTED / SUSPENDED in ConnectivityService,
        // and instead use isConnectedOrConnecting().
        mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
        mLinkUp = false;
        updateAgent();
        mLinkProperties = new LinkProperties();
        mNetworkAgent = null;
        setInterfaceInfoLocked("", null);
        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
        mFactory.unregister();
    }

    private void initNetworkCapabilities() {
        mNetworkCapabilities = new NetworkCapabilities();
        mNetworkCapabilities.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET);
        mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        // We have no useful data on bandwidth. Say 100M up and 100M down. :-(
        mNetworkCapabilities.setLinkUpstreamBandwidthKbps(100 * 1000);
        mNetworkCapabilities.setLinkDownstreamBandwidthKbps(100 * 1000);
    }

    public synchronized boolean isTrackingInterface() {
        return !TextUtils.isEmpty(mIface);
    }

    /**
     * Set interface information and notify listeners if availability is changed.
     * This should be called with the lock held.
     */
    private void setInterfaceInfoLocked(String iface, String hwAddr) {
        boolean oldAvailable = isTrackingInterface();
        mIface = iface;
        mHwAddr = hwAddr;
        boolean available = isTrackingInterface();

        if (oldAvailable != available) {
            int n = mListeners.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
                    mListeners.getBroadcastItem(i).onAvailabilityChanged(available);
                } catch (RemoteException e) {
                    // Do nothing here.
                }
            }
            mListeners.finishBroadcast();
        }
    }

    synchronized void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
        if (isTrackingInterface()) {
            pw.println("Tracking interface: " + mIface);
            pw.increaseIndent();
            pw.println("MAC address: " + mHwAddr);
            pw.println("Link state: " + (mLinkUp ? "up" : "down"));
            pw.decreaseIndent();
        } else {
            pw.println("Not tracking any interface");
        }

        pw.println();
        pw.println("NetworkInfo: " + mNetworkInfo);
        pw.println("LinkProperties: " + mLinkProperties);
        pw.println("NetworkAgent: " + mNetworkAgent);
        if (mIpManager != null) {
            pw.println("IpManager:");
            pw.increaseIndent();
            mIpManager.dump(fd, pw, args);
            pw.decreaseIndent();
        }
    }
}

Modify file:

frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java

Add the following:

import android.net.EthernetManager;
import android.os.Looper;
import android.provider.Settings;
        int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao  
            if(enable != EthernetManager.ETH_STATE_ENABLED) {
                Log.i(TAG, "Ethernet is not enable");
            return;
         }
    //law
    class TstartThread extends Thread {
        public void run() {
            Looper.prepare();
            mTracker.start(mContext, mHandler);
            mStarted.set(true);
            Looper.loop();
        }
    }
  
    public void Trackstart() { //add by hclydao
        new TstartThread().start();
    }
  
    public void Trackstop() {
        Log.i(TAG, "Stop Ethernet service");
        Thread tstopthread = new Thread(new Runnable() {
            public void run() {
                Looper.prepare();
                mTracker.stop();
                mStarted.set(false);
                Looper.loop();
            }
        });
        tstopthread.start();
    }

Complete contents are as follows:

/*
 * 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 com.android.server.ethernet;

import android.content.Context;
import android.content.pm.PackageManager;
import android.net.IEthernetManager;
import android.net.IEthernetServiceListener;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.provider.Settings;
import android.net.EthernetManager;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.os.Looper;
import android.provider.Settings;

import com.android.internal.util.IndentingPrintWriter;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * EthernetServiceImpl handles remote Ethernet operation requests by implementing
 * the IEthernetManager interface.
 *
 * @hide
 */
public class EthernetServiceImpl extends IEthernetManager.Stub {
    private static final String TAG = "EthernetServiceImpl";

    private final Context mContext;
    private final EthernetConfigStore mEthernetConfigStore;
    private final AtomicBoolean mStarted = new AtomicBoolean(false);
    private IpConfiguration mIpConfiguration;

    private Handler mHandler;
    private final EthernetNetworkFactory mTracker;
    private final RemoteCallbackList<IEthernetServiceListener> mListeners =
            new RemoteCallbackList<IEthernetServiceListener>();

    public EthernetServiceImpl(Context context) {
        mContext = context;
        Log.i(TAG, "Creating EthernetConfigStore");
        mEthernetConfigStore = new EthernetConfigStore();
        mIpConfiguration = mEthernetConfigStore.readIpAndProxyConfigurations();

        Log.i(TAG, "Read stored IP configuration: " + mIpConfiguration);

        mTracker = new EthernetNetworkFactory(mListeners);
    }

    private void enforceAccessPermission() {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE,
                "EthernetService");
    }

    private void enforceConnectivityInternalPermission() {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CONNECTIVITY_INTERNAL,
                "ConnectivityService");
    }

    public void start() {
        Log.i(TAG, "Starting Ethernet service");

        HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");
        handlerThread.start();
        mHandler = new Handler(handlerThread.getLooper());
        int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao  
            if(enable != EthernetManager.ETH_STATE_ENABLED) {
                Log.i(TAG, "Ethernet is not enable");
            return;
         }

        mTracker.start(mContext, mHandler);

        mStarted.set(true);
    }
    //law
    class TstartThread extends Thread {
        public void run() {
            Looper.prepare();
            mTracker.start(mContext, mHandler);
            mStarted.set(true);
            Looper.loop();
        }
    }
  
    public void Trackstart() { //add by hclydao
        new TstartThread().start();
    }
  
    public void Trackstop() {
        Log.i(TAG, "Stop Ethernet service");
        Thread tstopthread = new Thread(new Runnable() {
            public void run() {
                Looper.prepare();
                mTracker.stop();
                mStarted.set(false);
                Looper.loop();
            }
        });
        tstopthread.start();
    }
    /**
     * Get Ethernet configuration
     * @return the Ethernet Configuration, contained in {@link IpConfiguration}.
     */
    @Override
    public IpConfiguration getConfiguration() {
        enforceAccessPermission();

        synchronized (mIpConfiguration) {
            return new IpConfiguration(mIpConfiguration);
        }
    }

    /**
     * Set Ethernet configuration
     */
    @Override
    public void setConfiguration(IpConfiguration config) {
        if (!mStarted.get()) {
            Log.w(TAG, "System isn't ready enough to change ethernet configuration");
        }

        enforceConnectivityInternalPermission();

        synchronized (mIpConfiguration) {
            mEthernetConfigStore.writeIpAndProxyConfigurations(config);

            // TODO: this does not check proxy settings, gateways, etc.
            // Fix this by making IpConfiguration a complete representation of static configuration.
            if (!config.equals(mIpConfiguration)) {
                mIpConfiguration = new IpConfiguration(config);
                mTracker.stop();
                mTracker.start(mContext, mHandler);
            }
        }
    }

    /**
     * Indicates whether the system currently has one or more
     * Ethernet interfaces.
     */
    @Override
    public boolean isAvailable() {
        enforceAccessPermission();
        return mTracker.isTrackingInterface();
    }

    /**
     * Addes a listener.
     * @param listener A {@link IEthernetServiceListener} to add.
     */
    public void addListener(IEthernetServiceListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener must not be null");
        }
        enforceAccessPermission();
        mListeners.register(listener);
    }

    /**
     * Removes a listener.
     * @param listener A {@link IEthernetServiceListener} to remove.
     */
    public void removeListener(IEthernetServiceListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener must not be null");
        }
        enforceAccessPermission();
        mListeners.unregister(listener);
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump EthernetService from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
            return;
        }

        pw.println("Current Ethernet state: ");
        pw.increaseIndent();
        mTracker.dump(fd, pw, args);
        pw.decreaseIndent();

        pw.println();
        pw.println("Stored Ethernet configuration: ");
        pw.increaseIndent();
        pw.println(mIpConfiguration);
        pw.decreaseIndent();

        pw.println("Handler:");
        pw.increaseIndent();
        mHandler.dump(new PrintWriterPrinter(pw), "EthernetServiceImpl");
        pw.decreaseIndent();
    }
}

Modify file:

frameworks/base/core/res/res/values/config.xml

Add the following:

        <item><xliff:g id="id">@string/status_bar_ethernet</xliff:g></item>
    <string translatable="false" name="status_bar_ethernet">ethernet</string>

Modify the document:

frameworks/base/core/java/android/content/Intent.java

Add the following:

    /** @hide */
    public static final String ACTION_ETHERNET_ON = "android.intent.action.ETHERNET_ON";

    /** @hide */
    public static final String ACTION_ETHERNET_CONNECTED = "android.intent.action.ETHERNET_CONNECTED";

    /** @hide */
    public static final String ACTION_ETHERNET_DISCONNECTED = "android.intent.action.ETHERNET_DISCONNECTED";
 
    /** @hide */
    public static final String ACTION_ETHERNET_OFF = "android.intent.action.ETHERNET_OFF";

    /** @hide */
    public static final String ACTION_ETHERNET_STATUSBAR_READY  = "android.intent.action.ETHERNET_STATUSBAR_READY";


Modify file:

frameworks/base/core/res/res/values/symbols.xml

Add the following:

  <java-symbol type="string" name="status_bar_ethernet" />

New file:

frameworks/base/packages/SystemUI/res/drawable/ethernet_connected.png

New file:

frameworks/base/packages/SystemUI/res/drawable/ethernet_connecting.png

New file:

frameworks/base/packages/SystemUI/res/drawable/ethernet_disconnected.png

Modify file:

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java

Add the following:

import android.provider.Settings;
import android.net.EthernetManager;
    private static final boolean DEBUG = true; //Log.isLoggable(TAG, Log.DEBUG);
    private final String mSlotEthernet;
    private static final int ETHERNET_ON = 1;
    private static final int ETHERNET_OFF = 2;
    private static final int ETHERNET_CONNECTED = 3;
    private static final int ETHERNET_DISCONNECTED = 4;
    private boolean mEthernetConnected = false;

In PhoneStatusBarPolicy, add:

        mSlotEthernet = context.getString(com.android.internal.R.string.status_bar_ethernet);
        filter.addAction(Intent.ACTION_ETHERNET_ON);
        filter.addAction(Intent.ACTION_ETHERNET_OFF);
        filter.addAction(Intent.ACTION_ETHERNET_CONNECTED);
        filter.addAction(Intent.ACTION_ETHERNET_DISCONNECTED);
        mIconController.setIcon(mSlotEthernet, R.drawable.ethernet_disconnected, null);
        mIconController.setIconVisibility(mSlotEthernet, false);
        Log.d(TAG, "klein----PhoneStatusBarPolicy--broadcasts register ");
        // listen for broadcasts
        Log.d(TAG, "klein----PhoneStatusBarPolicy--tell ethernet that statusbar is ready");
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_ETHERNET_STATUSBAR_READY);
        mContext.sendBroadcast(intent);

Add the "updateEthernet" method:

    private void updateEthernet(int mEthernetConnectedNewState) {
        Log.d(TAG, "klein----updateEthernet--isEthernetConnected = " + mEthernetConnectedNewState);
	
        int ethernetIconId = 0;
        String ethernetDescription = null;
	
        int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);
        boolean isEthernetOpened = (enable == EthernetManager.ETH_STATE_ENABLED);
        Log.d(TAG, "klein----updateEthernet--isEthernetOpened = " + isEthernetOpened);
	
        if ((mEthernetConnectedNewState == ETHERNET_CONNECTED)){
            mEthernetConnected = true;
        }else if (mEthernetConnectedNewState == ETHERNET_DISCONNECTED){
            mEthernetConnected = false;
        }
			
        if (isEthernetOpened){
			Log.d(TAG, "klein----set false");
            mIconController.setIconVisibility(mSlotEthernet, false);

            if (mEthernetConnected){
                mIconController.setIcon(mSlotEthernet, R.drawable.ethernet_connected, null);
                mIconController.setIconVisibility(mSlotEthernet, true);
            } else {
                mIconController.setIconVisibility(mSlotEthernet, false);
            }
        } else {
            mEthernetConnected = false;
            mIconController.setIconVisibility(mSlotEthernet, false);
        }
    }

In the "onReceive" method of "broadcastreceiver mmintentreceiver", add:

            else if (action.equals(Intent.ACTION_ETHERNET_ON)) {
                updateEthernet(ETHERNET_ON);
            }else if (action.equals(Intent.ACTION_ETHERNET_CONNECTED)) {
                updateEthernet(ETHERNET_CONNECTED);
            }else if (action.equals(Intent.ACTION_ETHERNET_DISCONNECTED)) {
                updateEthernet(ETHERNET_DISCONNECTED);
            }else if (action.equals(Intent.ACTION_ETHERNET_OFF)) {
                updateEthernet(ETHERNET_OFF);
            }

 

Modification of packages

Modify the document:

packages/apps/Settings/AndroidManifest.xml

Add the following:

        <activity android:name="Settings$EthernetSettingsActivity"
               android:label="@string/ethernet_settings"
               android:taskAffinity="">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <action android:name="com.android.settings.ETHERNET_SETTINGS" />
               <action android:name="android.settings.ETHERNET_SETTINGS" />
               <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.EthernetSettings" />
           <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
           	   android:resource="@string/ethernet_settings"
           	   style="box-sizing: border-box;" />
           <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
               android:value="true"
               style="box-sizing: border-box;"/>
        </activity>
		<activity android:name="Settings$EthernetSettingsActivity"
               android:label="@string/ethernet_settings"
               android:taskAffinity=""
               android:icon="@drawable/ic_settings_dock"
               android:configChanges="orientation|keyboardHidden|screenSize">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <action android:name="com.android.settings.ETHERNET_SETTINGS" />
               <action android:name="android.settings.ETHERNET_SETTINGS" />
               <category android:name="android.intent.category.DEFAULT" />
               <category android:name="android.intent.category.VOICE_LAUNCH" />
               <category android:name="com.android.settings.SHORTCUT" />
           </intent-filter>
           <intent-filter android:priority="4">
                <action android:name="com.android.settings.action.SETTINGS" />
           </intent-filter>
           <meta-data android:name="com.android.settings.category"
               android:value="com.android.settings.category.wireless" />
           <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
               android:value="com.android.settings.ethernet.EthernetSettings" />
           <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
               android:value="true" />
       </activity>
        <!-- Keep compatibility with old shortcuts. -->
        <activity-alias android:name=".ethernet.EthernetSettings"
                android:taskAffinity="com.android.settings"
                android:label="@string/ethernet_settings"
                android:icon="@drawable/ic_settings_dock"
                android:targetActivity="Settings$EthernetSettingsActivity"
                android:configChanges="orientation|keyboardHidden|screenSize"
                android:exported="true">
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="com.android.settings.wifi.EthernetSettings" />
        </activity-alias>

 

Add file:

packages/apps/Settings/res/layout/eth_configure.xml

The complete document is as follows:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

    <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="8dip"
            android:orientation="vertical">

            <LinearLayout
                android:id="@+id/table"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical">
            </LinearLayout>

        <!-- Connection type -->
	<TextView android:id="@+id/eth_con_type"
                style="?android:attr/textAppearanceSmall"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dip"
                android:text="@string/eth_con_type" />
        <RadioGroup android:id="@+id/con_type"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                >
                <RadioButton android:id="@+id/dhcp_radio"
			style="?android:attr/textAppearanceSmall"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content"
			android:text="@string/eth_con_type_dhcp"
                ></RadioButton>
                <RadioButton android:id="@+id/manual_radio"
			style="?android:attr/textAppearanceSmall"
			android:layout_width="fill_parent"
			android:layout_height="wrap_content"
			android:text="@string/eth_con_type_manual"
                ></RadioButton>
        </RadioGroup>

        <!-- IP address -->
        <LinearLayout android:id="@+id/enterprise_wrapper"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="0dip"
            android:orientation="vertical">
                <TextView android:id="@+id/ipaddr_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_ipaddr" />
                <EditText android:id="@+id/ipaddr_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
<!--
                <TextView android:id="@+id/netmask_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_mask" />
                <EditText android:id="@+id/netmask_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
-->
                <TextView android:id="@+id/prefix_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_network_prefix_length" />
                <EditText android:id="@+id/prefix_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />

                <TextView android:id="@+id/dns_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_dns" />
                <EditText android:id="@+id/eth_dns_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
                <TextView android:id="@+id/gw_text"
                        style="?android:attr/textAppearanceSmall"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dip"
                        android:text="@string/eth_gw" />
                <EditText android:id="@+id/eth_gw_edit"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="2dip"
                        android:singleLine="true" />
        </LinearLayout>

    </LinearLayout>

</ScrollView>

Modify file:

packages/apps/Settings/res/values/strings.xml

Add the following:

    <string name="ethernet_settings">Ethernet</string>
    <!-- Ethernet configuration dialog law-->
    <string name="eth_config_title">Configure Ethernet device</string>
    <string name="eth_setting">Ethernet</string>
    <string name="eth_dev_list">Ethernet Devices:</string>
    <string name="eth_con_type">Connection Type</string>
    <string name="eth_con_type_dhcp">DHCP</string>
    <string name="eth_con_type_manual">Static IP</string>
    <string name="eth_dns">DNS address</string>
    <string name="eth_gw">Gateway address</string>
    <string name="eth_ipaddr">IP address</string>
    <string name="eth_quick_toggle_title">Ethernet</string>
    <string name="eth_quick_toggle_summary">Turn on Ethernet</string>
    <string name="eth_conf_perf_title">Ethernet configuration</string>
    <string name="eth_conf_summary">Configure Ethernet devices</string>
    <string name="eth_mask">Netmask</string>
    <string name="eth_toggle_summary_off">Turn off Ethernet</string>
    <string name="eth_toggle_summary_on">Turn on Ethernet</string>
    <string name="eth_settings_error">Failed to set: Please enter the valid characters 0~255</string>
    <string name="eth_settings_empty">can\'t be empty</string>
    <!-- Label for the <a target=_blank href="http://www.07net01.com/tags-Network-0.html" target="_blank" class="infotextkey" style="box-sizing: border-box; background-color: transparent; color: rgb(66, 139, 202);">Network</a> prefix of the network [CHAR LIMIT=25]-->
    <string name="eth_network_prefix_length">Network prefix length</string>

Add file:

packages/apps/Settings/res/xml/ethernet_settings.xml

The complete contents are as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:title="@string/ethernet_settings"
        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
        <Preference
            android:title="@string/eth_conf_perf_title"
            android:summary="@string/eth_conf_summary"
            android:key="ETHERNET_CONFIG"
            android:persistent="true" />
</PreferenceScreen>

Modify file:

packages/apps/Settings/src/com/android/settings/Settings.java

Add the following:

    public static class EthernetSettingsActivity extends SettingsActivity { /*empty */ }

Modify file:

packages/apps/Settings/src/com/android/settings/SettingsActivity.java

Add the following:

import com.android.settings.ethernet.EthernetSettings;

In "string [] settings" for "restricted", add:

            Settings.EthernetSettingsActivity.class.getName(),

In "string [] entry" add:

            EthernetSettings.class.getName(),//add by law

In the "doUpdateTilesList" method, add:

		setTileEnabled(new ComponentName(packageName,
			    Settings.EthernetSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);

New file:

packages/apps/Settings/src/com/android/settings/ethernet/EthernetDialog.java

The complete contents are as follows:

/*
 * Copyright (C) 2010 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 com.android.settings.R;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.util.Slog;
import android.view.inputmethod.InputMethodManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.os.Environment;
import android.util.SparseArray;
import android.net.StaticIpConfiguration;
import android.net.EthernetManager;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.Iterator;
import android.text.TextUtils;
import android.net.LinkAddress;
import android.net.NetworkUtils;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import com.android.settings.Utils;
import android.widget.Toast;
import android.net.EthernetManager;
import android.provider.Settings;

class EthernetDialog extends AlertDialog implements DialogInterface.OnClickListener, DialogInterface.OnShowListener,
        DialogInterface.OnDismissListener{
    private final String TAG = "EthConfDialog";
    private static final boolean localLOGV = true;

    /* This value comes from "wifi_ip_settings" resource array */
    private static final int DHCP = 0;
    private static final int STATIC_IP = 1;
    private IpAssignment mIpAssignment = IpAssignment.DHCP;
	private StaticIpConfiguration mStaticIpConfiguration = null;

    private View mView;
    private RadioButton mConTypeDhcp;
    private RadioButton mConTypeManual;
    private EditText mIpaddr;
    private EditText mDns;
    private EditText mGw;
    //private EditText mMask;
	private EditText mprefix;

    private Context mContext;
	private EthernetManager mEthManager;
	private ConnectivityManager mCM;

    public EthernetDialog(Context context,EthernetManager EthManager,ConnectivityManager cm) {
        super(context);
        Slog.d(TAG, "klein----EthernetDialog");
        mContext = context;
        mEthManager = EthManager;
        mCM = cm;
        buildDialogContent(context);
        setOnShowListener(this);
        setOnDismissListener(this);
    }

    public void onShow(DialogInterface dialog) {
        if (localLOGV) Slog.d(TAG, "onShow");
		UpdateInfo();
        // soft keyboard pops up on the disabled EditText. Hide it.
        InputMethodManager imm = (InputMethodManager)mContext.getSystemService(
                Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
                InputMethodManager.HIDE_IMPLICIT_ONLY);
    }

    public void onDismiss(DialogInterface dialog) {
        if (localLOGV) Slog.d(TAG, "onDismiss");
    }

	public void UpdateInfo() {
		int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao
		if(enable == EthernetManager.ETH_STATE_ENABLED) {
		//if(mEthManager.isAvailable()) {
			IpConfiguration ipinfo = mEthManager.getConfiguration();
			if(ipinfo != null) {
				if(ipinfo.ipAssignment == IpAssignment.DHCP) {
					mConTypeDhcp.setChecked(true);
		            mIpaddr.setEnabled(false);
		            mDns.setEnabled(false);
		            mGw.setEnabled(false);
		            //mMask.setEnabled(true);
					mprefix.setEnabled(false);
					mDns.setText("");
					mGw.setText("");
					mprefix.setText("");
					mIpaddr.setText("");
					if(mCM != null) {
						LinkProperties lp  = mCM.getLinkProperties(ConnectivityManager.TYPE_ETHERNET);
						if(lp != null) {
							mIpaddr.setText(formatIpAddresses(lp));
						}
					}
				} else {
					mConTypeManual.setChecked(true);
		            mIpaddr.setEnabled(true);
		            mDns.setEnabled(true);
		            mGw.setEnabled(true);
		            //mMask.setEnabled(true);
					mprefix.setEnabled(true);
					StaticIpConfiguration staticConfig = ipinfo.getStaticIpConfiguration();
					if (staticConfig != null) {
						if (staticConfig.ipAddress != null) {
							mIpaddr.setText(staticConfig.ipAddress.getAddress().getHostAddress());
		                    mprefix.setText(Integer.toString(staticConfig.ipAddress.getNetworkPrefixLength()));
						}
		                if (staticConfig.gateway != null) {
		                    mGw.setText(staticConfig.gateway.getHostAddress());
		                }
		                Iterator<InetAddress> dnsIterator = staticConfig.dnsServers.iterator();
		                if (dnsIterator.hasNext()) {
		                    mDns.setText(dnsIterator.next().getHostAddress());
		                }
					}
				}
			}
		}
	}

    public int buildDialogContent(Context context) {
        this.setTitle(R.string.eth_config_title);
        this.setView(mView = getLayoutInflater().inflate(R.layout.eth_configure, null));
        mConTypeDhcp = (RadioButton) mView.findViewById(R.id.dhcp_radio);
        mConTypeManual = (RadioButton) mView.findViewById(R.id.manual_radio);
        mIpaddr = (EditText)mView.findViewById(R.id.ipaddr_edit);
		mprefix = (EditText)mView.findViewById(R.id.prefix_edit);
       // mMask = (EditText)mView.findViewById(R.id.netmask_edit);
        mDns = (EditText)mView.findViewById(R.id.eth_dns_edit);
        mGw = (EditText)mView.findViewById(R.id.eth_gw_edit);

        mConTypeDhcp.setChecked(true);
        mConTypeManual.setChecked(false);
        mIpaddr.setEnabled(false);
       // mMask.setEnabled(false);
		mprefix.setEnabled(false);
        mDns.setEnabled(false);
        mGw.setEnabled(false);

        mConTypeManual.setOnClickListener(new RadioButton.OnClickListener() {
            public void onClick(View v) {
                mIpaddr.setEnabled(true);
                mDns.setEnabled(true);
                mGw.setEnabled(true);
                //mMask.setEnabled(true);
				mprefix.setEnabled(true);
				mIpAssignment = IpAssignment.STATIC;
				if(TextUtils.isEmpty(mIpaddr.getText().toString()))
					mIpaddr.setText("192.168.1.15");
				if(TextUtils.isEmpty(mDns.getText().toString()))
					mDns.setText("192.168.1.1");
				if(TextUtils.isEmpty(mGw.getText().toString()))
					mGw.setText("192.168.1.1");
				if(TextUtils.isEmpty(mprefix.getText().toString()))
					mprefix.setText("24");
            }
        });

        mConTypeDhcp.setOnClickListener(new RadioButton.OnClickListener() {
            public void onClick(View v) {
                mIpaddr.setEnabled(false);
                mDns.setEnabled(false);
                mGw.setEnabled(false);
                //mMask.setEnabled(false);
				mprefix.setEnabled(false);
				mIpAssignment = IpAssignment.DHCP;
				mDns.setText("");
				mGw.setText("");
				mprefix.setText("");
				mIpaddr.setText("");
            }
        });

        this.setInverseBackgroundForced(true);
        this.setButton(BUTTON_POSITIVE, context.getText(R.string.menu_save), this);
        this.setButton(BUTTON_NEGATIVE, context.getText(R.string.menu_cancel), this);
		UpdateInfo();
		return 0;
    }

    private String formatIpAddresses(LinkProperties prop) {
        if (prop == null) return null;
        Iterator<InetAddress> iter = prop.getAllAddresses().iterator();
        // If there are no entries, return null
        if (!iter.hasNext()) return null;
        // Concatenate all available addresses, comma separated
        String addresses = "";
        while (iter.hasNext()) {
            addresses += iter.next().getHostAddress();
            if (iter.hasNext()) addresses += "\n";
        }
        return addresses;
    }

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

    private int validateIpConfigFields(StaticIpConfiguration staticIpConfiguration) {

        String ipAddr = mIpaddr.getText().toString();

        Inet4Address inetAddr = getIPv4Address(ipAddr);
        if (inetAddr == null) {
            return 2;
        }
/*
		String netmask = mMask.getText().toString();
        if (TextUtils.isEmpty(netmask)) 
			return 11;
		Inet4Address netmas = getIPv4Address(netmask);
        if (netmas == null) {
            return 12;
        }
		int nmask = NetworkUtils.inetAddressToInt(netmas);
		int prefixlength = NetworkUtils.netmaskIntToPrefixLength(nmask);
*/
        int networkPrefixLength = -1;
        try {
            networkPrefixLength = Integer.parseInt(mprefix.getText().toString());
            if (networkPrefixLength < 0 || networkPrefixLength > 32) {
                return 3;
            }
            staticIpConfiguration.ipAddress = new LinkAddress(inetAddr, networkPrefixLength);
        } catch (NumberFormatException e) {
            // Set the hint as default after user types in ip address
        }

        String gateway = mGw.getText().toString();

        InetAddress gatewayAddr = getIPv4Address(gateway);
        if (gatewayAddr == null) {
            return 4;
        }
        staticIpConfiguration.gateway = gatewayAddr;

        String dns = mDns.getText().toString();
        InetAddress dnsAddr = null;

		dnsAddr = getIPv4Address(dns);
		if (dnsAddr == null) {
		    return 5;
		}

		staticIpConfiguration.dnsServers.add(dnsAddr);

        return 0;
    }

    private void handle_saveconf() {
        if (mConTypeDhcp.isChecked()) {
			Slog.i(TAG,"mode dhcp");
			mEthManager.setConfiguration(new IpConfiguration(mIpAssignment, ProxySettings.NONE,
                                null, null));
        } else {
            Slog.i(TAG,"mode static ip");
			if(isIpAddress(mIpaddr.getText().toString())
				&& isIpAddress(mGw.getText().toString())
				&& isIpAddress(mDns.getText().toString())) {
				
				if(TextUtils.isEmpty(mIpaddr.getText().toString())
					|| TextUtils.isEmpty(mprefix.getText().toString())
					|| TextUtils.isEmpty(mGw.getText().toString())
					|| TextUtils.isEmpty(mDns.getText().toString())) {
					Toast.makeText(mContext, R.string.eth_settings_empty, Toast.LENGTH_LONG).show();
		            return ;
				}

				mStaticIpConfiguration = new StaticIpConfiguration();
		        int result = validateIpConfigFields(mStaticIpConfiguration);
		        if (result != 0) {
					Toast.makeText(mContext, " error id is " + result, Toast.LENGTH_LONG).show();
		            return ;
		        } else {
					mEthManager.setConfiguration( new IpConfiguration(mIpAssignment, ProxySettings.NONE,
		                                mStaticIpConfiguration, null));
				}
			} else
				Toast.makeText(mContext, R.string.eth_settings_error, Toast.LENGTH_LONG).show();
		}
    }

    private boolean isIpAddress(String value) {
        int start = 0;
        int end = value.indexOf('.');
        int numBlocks = 0;

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

            try {
                int block = Integer.parseInt(value.substring(start, end));
                if ((block > 255) || (block < 0)) {
                        return false;
                }
            } catch (NumberFormatException e) {
                    return false;
            }

            numBlocks++;

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

    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case BUTTON_POSITIVE:
                handle_saveconf();
                break;
            case BUTTON_NEGATIVE:
                //Don't need to do anything
                break;
            default:
        }
    }

}

Add file:

packages/apps/Settings/src/com/android/settings/ethernet/EthernetEnabler.java

/*
 * Copyright (C) 2010 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.
 */

/*
 * developed by hclydao@gmail.com
 */
package com.android.settings.ethernet;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.preference.CheckBoxPreference;

import java.util.ArrayList;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.R;
import com.android.settings.widget.SwitchBar;
import com.android.settings.SettingsActivity;
import android.widget.Switch;
import android.util.Slog;
import android.net.EthernetManager;
import android.provider.Settings;

public class EthernetEnabler implements SwitchBar.OnSwitchChangeListener {
	private final String TAG = "EthernetEnabler";
    private Context mContext;
    private SwitchBar mSwitchBar;
	private boolean mListeningToOnSwitchChange = false;
	private EthernetDialog mEthDialog = null;
	private EthernetManager mEthManager;
    public void setConfigDialog(EthernetDialog Dialog) {
        mEthDialog = Dialog;
    }

    public EthernetEnabler(Context context, SwitchBar switchBar,EthernetManager ethernetManager) {
        mContext = context;
        mSwitchBar = switchBar;
		mEthManager = ethernetManager;
        setupSwitchBar();
    }

    public void resume(Context context) {
        mContext = context;
        if (!mListeningToOnSwitchChange) {
            mSwitchBar.addOnSwitchChangeListener(this);
            mListeningToOnSwitchChange = true;
        }
    }

    public void pause() {
        if (mListeningToOnSwitchChange) {
            mSwitchBar.removeOnSwitchChangeListener(this);
            mListeningToOnSwitchChange = false;
        }
    }

    public void setupSwitchBar() {
        if (!mListeningToOnSwitchChange) {
            mSwitchBar.addOnSwitchChangeListener(this);
            mListeningToOnSwitchChange = true;
        }
        mSwitchBar.show();
		int enable = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.ETHERNET_ON,0);//add by hclydao
		if(enable == EthernetManager.ETH_STATE_ENABLED) {
			mSwitchBar.setChecked(true);
			Log.d(TAG,"setupSwitchBar on");
			Intent intent = new Intent();
			intent.setAction(Intent.ACTION_ETHERNET_ON);
			mContext.sendBroadcast(intent);
		} else {
			mSwitchBar.setChecked(false);
			Log.d(TAG,"setupSwitchBar off");
			Intent intent = new Intent();
			intent.setAction(Intent.ACTION_ETHERNET_OFF);
			mContext.sendBroadcast(intent);
		}
    }

    public void teardownSwitchBar() {
        if (mListeningToOnSwitchChange) {
            mSwitchBar.removeOnSwitchChangeListener(this);
            mListeningToOnSwitchChange = false;
        }
        mSwitchBar.hide();
    }

    @Override
    public void onSwitchChanged(Switch switchView, boolean isChecked) {
        Log.d(TAG,"klein--isChecked = " + isChecked);
        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ETHERNET_ON,
        isChecked ? EthernetManager.ETH_STATE_ENABLED : EthernetManager.ETH_STATE_DISABLED);

		if(isChecked) {
			//if(mEthDialog != null)
				//mEthDialog.show();
		} else {
            Log.d(TAG,"klein--onSwitchChanged off");
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_ETHERNET_OFF);
            mContext.sendBroadcast(intent);

			if(mEthManager != null)
				mEthManager.stop();	
		}

		if(isChecked){
		    Log.d(TAG,"klein--onSwitchChanged on");
		    Intent intent = new Intent();
		    intent.setAction(Intent.ACTION_ETHERNET_ON);
		    mContext.sendBroadcast(intent);
		    if(mEthManager != null){
		        mEthManager.start();
		    }
		}

    }
}

Add file:

packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java

/*
 * Copyright (C) 2010 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.
 */

/*
 * developed by hclydao@gmail.com
 */

package com.android.settings.ethernet;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.support.v7.preference.AndroidResources;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.EditTextPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceGroupAdapter;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceRecyclerViewAccessibilityDelegate;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.PreferenceViewHolder;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.preference.CheckBoxPreference;

import java.util.ArrayList;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.R;
import com.android.settings.widget.SwitchBar;
import com.android.settings.SettingsActivity;
import android.widget.Switch;
import android.app.Activity;
import android.app.ActivityManager;
import android.net.EthernetManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.util.Slog;
import android.widget.Toast;
import android.os.Looper;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;


public class EthernetSettings extends SettingsPreferenceFragment implements
        Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener{
	private static final String TAG = "EthernetSettings";
	private EthernetEnabler mEthEnabler;
    private static final String KEY_CONF_ETH = "ETHERNET_CONFIG";
	private EthernetDialog mEthDialog = null;
	private Preference mEthConfigPref;
	private ConnectivityManager mCM;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.ethernet_settings);
        mEthConfigPref = (Preference)findPreference(KEY_CONF_ETH);
        mEthConfigPref.setOnPreferenceChangeListener(this);
        mEthConfigPref.setOnPreferenceClickListener(this);
    }

    @Override
    public void onStart() {
        super.onStart();
        // On/off switch is hidden for Setup Wizard (returns null)
        mEthEnabler = createEthernetEnabler();
		mCM = (ConnectivityManager)getActivity().getSystemService(
		        Context.CONNECTIVITY_SERVICE);
		mEthDialog = new EthernetDialog(getActivity(),(EthernetManager)getSystemService(Context.ETHERNET_SERVICE),mCM);
		mEthEnabler.setConfigDialog(mEthDialog);
    }

    @Override
    public void onResume() {
        final Activity activity = getActivity();
        super.onResume();
        if (mEthEnabler != null) {
            mEthEnabler.resume(activity);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mEthEnabler != null) {
            mEthEnabler.pause();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        if (mEthEnabler != null) {
            mEthEnabler.teardownSwitchBar();
        }
    }

    /**
     * @return new WifiEnabler or null (as overridden by WifiSettingsForSetupWizard)
     */
    /* package */ 
	EthernetEnabler createEthernetEnabler() {
        final SettingsActivity activity = (SettingsActivity) getActivity();
        return new EthernetEnabler(activity, activity.getSwitchBar(),(EthernetManager)getSystemService(Context.ETHERNET_SERVICE));
    }

    public boolean onPreferenceChange(Preference preference, Object objValue) {
        return true;
    }

    /**
    * klein.zhou@quectel.com
    * onPreferenceTreeClick
    */
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
        Log.d(TAG, "leave empty");
        return false;
    }

    /**
    * klein.zhou@quectel.com
    * onPreferenceClick
    */
    public boolean onPreferenceClick(Preference preference){
        Log.d(TAG, "klein---onPreferenceClick");
			 if (preference == mEthConfigPref) {
                 final SettingsActivity activity = (SettingsActivity) getActivity();
                 if(activity.getSwitchBar().isChecked()) {
                     if(mEthDialog != null){
                        mEthDialog.show();
                     }
                 } else {
                     Toast.makeText(getActivity(), "please turn on ethernet",
                     Toast.LENGTH_LONG).show();
                  }
			 }
			 return false;
		 }

    @Override
	protected int getMetricsCategory(){
        return MetricsEvent.WIFI;
	}
}

Add file:

packages/apps/Settings/res/drawable-hdpi/ic_settings_dock_alpha.png

Add file:

packages/apps/Settings/res/drawable/ic_settings_dock.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2015 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.
-->

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_settings_dock_alpha"
    android:tint="?android:attr/colorAccent" />

 

Tags: Android xml Java Apache

Posted on Thu, 07 Nov 2019 10:35:54 -0800 by Saeven