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.youkuaiyun.com/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

加入以下内容:

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

修改完后像这样:

    <!-- 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>

 

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

 

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

 

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

添加以下内容:

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

 

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

加入以下内容:

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

 

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

添加以下内容:

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

 

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

完整文件内容如下:

<?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>

 

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

加入以下内容:

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

 

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

完整的内容如下:

<?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>

 

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

}

 

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

    }
}

 

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

 

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

新增此文件:

 

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" />

 

重新编译

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

 

本次小结

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值