Andorid:msm8909:在系统设置中添加以太网功能

目录

写在前面

本次目的

详细步骤

device的修改

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

device/qcom/msm8909/msm8909.mk

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

frameworks的修改

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

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

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

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

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

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

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

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

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

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

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

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

packages的修改

packages/apps/Settings/AndroidManifest.xml

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

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

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

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

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

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

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

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

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

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

重新编译

本次小结

 

写在前面

SOC:Qualcomm msm8909

Core-Board:SC20-CE QA/PJ

Base-Board:xxx

Linux Kernel:xxx

Android:7.1

 

本次目的

为安卓系统增加以太网功能,能够在系统设置菜单中找到以太网选项,完成以太网功能设置,并且在系统状态栏能够提示以太网网络状态。

如果您需要了解如何添加和调试相关驱动,比如这里用的RTL8152(USB转以太网芯片),可以参考我的这篇博客:

https://blog.csdn.net/uestc_ganlin/article/details/90692753

 

详细步骤

 

device的修改

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

添加以下内容:

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

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

 

device/qcom/msm8909/msm8909.mk

在“PRODUCT_COPY_FILES”中加入以下内容,注意上一个值的后面不要漏掉结束“\”:

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

修改完成后像这样:

# 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

 

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

加入以下内容:

       ethernet

修改完后像这样:

    
    
       managed_profile
       ime
       sync_failing
       sync_active
       cast
       hotspot
       location
       bluetooth
       nfc
       femtoicon
       tty
       speakerphone
       zen
       mute
       volume
       wifi
       ethernet
       cdma_eri
       data_connection
       phone_evdo_signal
       phone_signal
       battery
       alarm_clock
       secure
       clock
    

 

frameworks的修改

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

添加以下内容:

    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) {
 	   }
	}

 

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

添加以下内容:

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

 

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

添加以下内容:

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

 

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

添加以下依赖内容:

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

在此类中增加Handler属性: 

    private Handler mHandler;

 增加一个状态标志并创建一个广播接收:

	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);
	            }
	        }
	    }
	};

     在“updateInterfaceState”方法中加入更新状态的逻辑:


        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);
        }

在“onRequestNetwork”方法中 “ ipProvisioningThread”线程初始化时加入判断:

                          //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);
                           }  

在“start”方法中加入以下内容:

        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");

完整的文件内容如下:

/*
 * 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 config_ethernet_iface_regex
 * 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 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 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();
        }
    }
}

 

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

添加以下内容:

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();
    }

 完整内容如下:

/*
 * 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 mListeners =
            new RemoteCallbackList();

    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();
    }
}

 

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

添加以下内容:

        @string/status_bar_ethernet
    ethernet

 

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

加入以下内容:


    /** @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";


 

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

加入以下内容:

  

 

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

 

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

 

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

 

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

添加以下内容:

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;

在“PhoneStatusBarPolicy”中添加:

        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);

添加“updateEthernet” 方法:

    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);
        }
    }

 在“BroadcastReceiver mIntentReceiver”的“onReceive”方法中增加:

            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);
            }

 

packages的修改

packages/apps/Settings/AndroidManifest.xml

添加以下内容:

        
           
               
               
               
               
               
               
           
           
           
           
        
		
           
               
               
               
               
               
               
           
           
                
           
           
           
           
       
        
        
            
        

 

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

完整文件内容如下:




    

            
            

        
	
        
                
                
        

        
        
                
                

                
                

                
                
                
                
        

    


 

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

加入以下内容:

    Ethernet
    
    Configure Ethernet device
    Ethernet
    Ethernet Devices:
    Connection Type
    DHCP
    Static IP
    DNS address
    Gateway address
    IP address
    Ethernet
    Turn on Ethernet
    Ethernet configuration
    Configure Ethernet devices
    Netmask
    Turn off Ethernet
    Turn on Ethernet
    Failed to set: Please enter the valid characters 0~255
    can\'t be empty
    
    Network prefix length

 

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

完整的内容如下:





        

 

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

添加如下内容:

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

 

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

 添加以下内容:

import com.android.settings.ethernet.EthernetSettings;

在“String[] SETTINGS_FOR_RESTRICTED”中加入:

            Settings.EthernetSettingsActivity.class.getName(),

在“String[] ENTRY_FRAGMENTS”中加入:

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

在“doUpdateTilesList”方法中加入:

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

 

packages/apps/Settings/src/com/android/settings/ethernet/EthernetDialog.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.
 */

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 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 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:
        }
    }

}

 

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 [email protected]
 */
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();
		    }
		}

    }
}

 

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 [email protected]
 */

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;
    }

    /**
    * [email protected]
    * onPreferenceTreeClick
    */
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
        Log.d(TAG, "leave empty");
        return false;
    }

    /**
    * [email protected]
    * 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;
	}
}

 

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

新增此文件:

 

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

新增此文件:






 

重新编译

修改完上述文件后重新编译系统固件,使用新的固件启动系统,尝试相关操作。

 

本次小结

这个人很懒,什么也没有留下!

你可能感兴趣的:(Android)