1、Android 开机后,启动系统服务EthernetService(frameworks/opt/net/ethernet/java/com/android/server/ethnet/EthernetService.java),初始化一个EthernetServiceImpl(frameworks/opt/net/ethernet/java/com/android/server/ethnet/EthernetServiceImpl.java)对象,然后调用EthernetServiceImpl的start()方法;

2、初始化EthernetServiceImpl对象,创建EthernetConfigStore对象并调用readIpAndProxyConfigurations()方法,获取Ethernet 配置信息得到IpConfiguration对象;

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

  3、调用EthernetServiceImpl.start()方法,

    public void start() {        Log.i(TAG, "Starting Ethernet service");        HandlerThread handlerThread = new HandlerThread("EthernetServiceThread");        handlerThread.start();        mHandler = new Handler(handlerThread.getLooper());        mTracker.start(mContext, mHandler);        mStarted.set(true);    }

主要是进入EthernetNetworkFactory.start() ,注册相关监听,开启网络配置

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;//201808016 chen        // 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(!iface.equals("eth0")) {                            continue;                        }//                        if (mNMService.getInterfaceConfig(iface).hasFlag("running")) {                            updateInterfaceState(iface, true);                        }                        break;                    }                }            }        } catch (RemoteException|IllegalStateException e) {            Log.e(TAG, "Could not get list of interfaces " + e);        }    }

4、读取网络配置方法 

 EthernetConfigStore.readIpAndProxyConfigurations()如下,EthernetConfigStore 继承自 IpConfigStore

   private static final String ipConfigFile = Environment.getDataDirectory() +            "/misc/ethernet/ipconfig.txt";   public IpConfiguration readIpAndProxyConfigurations() {        SparseArray networks = readIpAndProxyConfigurations(ipConfigFile);//d调用IpConfigStore中的方法        if (networks.size() == 0) {            Log.w(TAG, "No Ethernet configuration found. Using default.");            return new IpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null);        }        if (networks.size() > 1) {            // Currently we only support a single Ethernet interface.            Log.w(TAG, "Multiple Ethernet configurations detected. Only reading first one.");        }        return networks.valueAt(0);    }

 5、设置以太网,通过EthManager.setConfiguration(IpConfiguration)方法事件是调用的EthernetServiceImpl.setConfiguration

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

在 setConfiguration中调用EthernetConfigStore.writeIpAndProxyConfigurations();将配置写入文件data//misc/ethernet/ipconfig.txt

 public void writeIpAndProxyConfigurations(IpConfiguration config) {        SparseArray networks = new SparseArray();        networks.put(0, config);        writeIpAndProxyConfigurations(ipConfigFile, networks);    }

同时调用mTracker.start(mContext, mHandler);

/**     * 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;        // 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")) {                            updateInterfaceState(iface, true);                        }                        break;                    }                }            }        } catch (RemoteException|IllegalStateException e) {            Log.e(TAG, "Could not get list of interfaces " + e);        }    }

发现进入maybeTrackInterface()方法,然后进入setInterfaceUp(),此时发现又调用了NetworkManagementService中的方法

frameworks/base/services/core/java/com/android/server/NetworkManagementService.java 

 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);        try {            setInterfaceUp(iface);        } catch (IllegalStateException e) {            Log.e(TAG, e.toString() + " (Ethernet IF abnormal)");            return false;        }        return true;    }  private void setInterfaceUp(String iface) {        // Bring up the interface so we get link status indications.        try {            NetworkUtils.stopDhcp(iface);            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);        }    }

发现在NetworkManagementService中主要是通过setInterfaceConfig方法与底层通信,通过构建Command ,然后通过NativeDaemonConnector发送命令。

frameworks/base/services/core/java/com/android/server/NativeDaemonConnector.java

  @Override    public void setInterfaceDown(String iface) {        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);        final InterfaceConfiguration ifcg = getInterfaceConfig(iface);        ifcg.setInterfaceDown();        setInterfaceConfig(iface, ifcg);    }    @Override    public void setInterfaceUp(String iface) {        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);        final InterfaceConfiguration ifcg = getInterfaceConfig(iface);        ifcg.setInterfaceUp();        setInterfaceConfig(iface, ifcg);    }@Override    public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);        LinkAddress linkAddr = cfg.getLinkAddress();        if (linkAddr == null || linkAddr.getAddress() == null) {            throw new IllegalStateException("Null LinkAddress given");        }        final Command cmd = new Command("interface", "setcfg", iface,                linkAddr.getAddress().getHostAddress(),                linkAddr.getPrefixLength());        for (String flag : cfg.getFlags()) {            cmd.appendArg(flag);        }        try {            mConnector.execute(cmd);        } catch (NativeDaemonConnectorException e) {            throw e.rethrowAsParcelableException();        }    }

 

附:IpConfigStore.java(frameworks/base/services/core/java/com/android/server/net/IpConfigStore.java),最终读取网络配置,设置网络等都会调用IpConfigStore中的方法

public class IpConfigStore {    private static final String TAG = "IpConfigStore";    private static final boolean DBG = true;    protected final DelayedDiskWrite mWriter;    /* IP and proxy configuration keys */    protected static final String ID_KEY = "id";    protected static final String IP_ASSIGNMENT_KEY = "ipAssignment";    protected static final String LINK_ADDRESS_KEY = "linkAddress";    protected static final String GATEWAY_KEY = "gateway";    protected static final String DNS_KEY = "dns";    protected static final String PROXY_SETTINGS_KEY = "proxySettings";    protected static final String PROXY_HOST_KEY = "proxyHost";    protected static final String PROXY_PORT_KEY = "proxyPort";    protected static final String PROXY_PAC_FILE = "proxyPac";    protected static final String EXCLUSION_LIST_KEY = "exclusionList";    protected static final String EOS = "eos";    protected static final int IPCONFIG_FILE_VERSION = 2;    public IpConfigStore() {        mWriter = new DelayedDiskWrite();    }    private boolean writeConfig(DataOutputStream out, int configKey,                                IpConfiguration config) throws IOException {        boolean written = false;        try {            switch (config.ipAssignment) {                case STATIC:                    out.writeUTF(IP_ASSIGNMENT_KEY);                    out.writeUTF(config.ipAssignment.toString());                    StaticIpConfiguration staticIpConfiguration = config.staticIpConfiguration;                    if (staticIpConfiguration != null) {                        if (staticIpConfiguration.ipAddress != null) {                            LinkAddress ipAddress = staticIpConfiguration.ipAddress;                            out.writeUTF(LINK_ADDRESS_KEY);                            out.writeUTF(ipAddress.getAddress().getHostAddress());                            out.writeInt(ipAddress.getPrefixLength());                        }                        if (staticIpConfiguration.gateway != null) {                            out.writeUTF(GATEWAY_KEY);                            out.writeInt(0);  // Default route.                            out.writeInt(1);  // Have a gateway.                            out.writeUTF(staticIpConfiguration.gateway.getHostAddress());                        }                        for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {                            out.writeUTF(DNS_KEY);                            out.writeUTF(inetAddr.getHostAddress());                        }                    }                    written = true;                    break;                case DHCP:                    out.writeUTF(IP_ASSIGNMENT_KEY);                    out.writeUTF(config.ipAssignment.toString());                    written = true;                    break;                case UNASSIGNED:                /* Ignore */                    break;                default:                    loge("Ignore invalid ip assignment while writing");                    break;            }            switch (config.proxySettings) {                case STATIC:                    ProxyInfo proxyProperties = config.httpProxy;    if(proxyProperties==null){break;}                    String exclusionList = proxyProperties.getExclusionListAsString();                    out.writeUTF(PROXY_SETTINGS_KEY);                    out.writeUTF(config.proxySettings.toString());                    out.writeUTF(PROXY_HOST_KEY);                    out.writeUTF(proxyProperties.getHost());                    out.writeUTF(PROXY_PORT_KEY);                    out.writeInt(proxyProperties.getPort());                    if (exclusionList != null) {                        out.writeUTF(EXCLUSION_LIST_KEY);                        out.writeUTF(exclusionList);                    }                    written = true;                    break;                case PAC:                    ProxyInfo proxyPacProperties = config.httpProxy;     if(proxyProperties==null){break;}                    out.writeUTF(PROXY_SETTINGS_KEY);                    out.writeUTF(config.proxySettings.toString());                    out.writeUTF(PROXY_PAC_FILE);                    out.writeUTF(proxyPacProperties.getPacFileUrl().toString());                    written = true;                    break;                case NONE:                    out.writeUTF(PROXY_SETTINGS_KEY);                    out.writeUTF(config.proxySettings.toString());                    written = true;                    break;                case UNASSIGNED:                    /* Ignore */                        break;                    default:                        loge("Ignore invalid proxy settings while writing");                        break;            }            if (written) {                out.writeUTF(ID_KEY);                out.writeInt(configKey);            }else{      loge("written false");      }        } catch (NullPointerException e) {            loge("Failure in writing " + config + e);        }        out.writeUTF(EOS);        return written;    }    public void writeIpAndProxyConfigurations(String filePath,                                              final SparseArray networks) {        mWriter.write(filePath, new DelayedDiskWrite.Writer() {            public void onWriteCalled(DataOutputStream out) throws IOException{                out.writeInt(IPCONFIG_FILE_VERSION);                for(int i = 0; i < networks.size(); i++) {                    writeConfig(out, networks.keyAt(i), networks.valueAt(i));                }            }        });    }    public SparseArray readIpAndProxyConfigurations(String filePath) {        SparseArray networks = new SparseArray();        DataInputStream in = null;        try {            in = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));            int version = in.readInt();            if (version != 2 && version != 1) {                loge("Bad version on IP configuration file, ignore read");                return null;            }            while (true) {                int id = -1;                // Default is DHCP with no proxy                IpAssignment ipAssignment = IpAssignment.DHCP;                ProxySettings proxySettings = ProxySettings.NONE;                StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();                String proxyHost = null;                String pacFileUrl = null;                int proxyPort = -1;                String exclusionList = null;                String key;                do {                    key = in.readUTF();                    try {                        if (key.equals(ID_KEY)) {                            id = in.readInt();                        } else if (key.equals(IP_ASSIGNMENT_KEY)) {                            ipAssignment = IpAssignment.valueOf(in.readUTF());                        } else if (key.equals(LINK_ADDRESS_KEY)) {                            LinkAddress linkAddr = new LinkAddress(                                    NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt());                            if (linkAddr.getAddress() instanceof Inet4Address &&                                    staticIpConfiguration.ipAddress == null) {                                staticIpConfiguration.ipAddress = linkAddr;                            } else {                                loge("Non-IPv4 or duplicate address: " + linkAddr);                            }                        } else if (key.equals(GATEWAY_KEY)) {                            LinkAddress dest = null;                            InetAddress gateway = null;                            if (version == 1) {                                // only supported default gateways - leave the dest/prefix empty                                gateway = NetworkUtils.numericToInetAddress(in.readUTF());                                if (staticIpConfiguration.gateway == null) {                                    staticIpConfiguration.gateway = gateway;                                } else {                                    loge("Duplicate gateway: " + gateway.getHostAddress());                                }                            } else {                                if (in.readInt() == 1) {                                    dest = new LinkAddress(                                            NetworkUtils.numericToInetAddress(in.readUTF()),                                            in.readInt());                                }                                if (in.readInt() == 1) {                                    gateway = NetworkUtils.numericToInetAddress(in.readUTF());                                }                                RouteInfo route = new RouteInfo(dest, gateway);                                if (route.isIPv4Default() &&                                        staticIpConfiguration.gateway == null) {                                    staticIpConfiguration.gateway = gateway;                                } else {                                    loge("Non-IPv4 default or duplicate route: " + route);                                }                            }                        } else if (key.equals(DNS_KEY)) {                            staticIpConfiguration.dnsServers.add(                                    NetworkUtils.numericToInetAddress(in.readUTF()));                        } else if (key.equals(PROXY_SETTINGS_KEY)) {                            proxySettings = ProxySettings.valueOf(in.readUTF());                        } else if (key.equals(PROXY_HOST_KEY)) {                            proxyHost = in.readUTF();                        } else if (key.equals(PROXY_PORT_KEY)) {                            proxyPort = in.readInt();                        } else if (key.equals(PROXY_PAC_FILE)) {                            pacFileUrl = in.readUTF();                        } else if (key.equals(EXCLUSION_LIST_KEY)) {                            exclusionList = in.readUTF();                        } else if (key.equals(EOS)) {                            break;                        } else {                            loge("Ignore unknown key " + key + "while reading");                        }                    } catch (IllegalArgumentException e) {                        loge("Ignore invalid address while reading" + e);                    }                } while (true);                if (id != -1) {                    IpConfiguration config = new IpConfiguration();                    networks.put(id, config);                    switch (ipAssignment) {                        case STATIC:                            config.staticIpConfiguration = staticIpConfiguration;                            config.ipAssignment = ipAssignment;                            break;                        case DHCP:                            config.ipAssignment = ipAssignment;                            break;                        case UNASSIGNED:                            loge("BUG: Found UNASSIGNED IP on file, use DHCP");                            config.ipAssignment = IpAssignment.DHCP;                            break;                        default:                            loge("Ignore invalid ip assignment while reading.");                            config.ipAssignment = IpAssignment.UNASSIGNED;                            break;                    }                    switch (proxySettings) {                        case STATIC:                            ProxyInfo proxyInfo =                                    new ProxyInfo(proxyHost, proxyPort, exclusionList);                            config.proxySettings = proxySettings;                            config.httpProxy = proxyInfo;                            break;                        case PAC:                            ProxyInfo proxyPacProperties = new ProxyInfo(pacFileUrl);                            config.proxySettings = proxySettings;                            config.httpProxy = proxyPacProperties;                            break;                        case NONE:                            config.proxySettings = proxySettings;                            break;                        case UNASSIGNED:                            loge("BUG: Found UNASSIGNED proxy on file, use NONE");                            config.proxySettings = ProxySettings.NONE;                            break;                        default:                            loge("Ignore invalid proxy settings while reading");                            config.proxySettings = ProxySettings.UNASSIGNED;                            break;                    }                } else {                    if (DBG) log("Missing id while parsing configuration");                }            }        } catch (EOFException ignore) {        } catch (IOException e) {            loge("Error parsing configuration: " + e);        } finally {            if (in != null) {                try {                    in.close();                } catch (Exception e) {}            }        }        return networks;    }    protected void loge(String s) {        Log.e(TAG, s);    }    protected void log(String s) {        Log.d(TAG, s);    }}

 

更多相关文章

  1. android 申请移动应用的签名生成方法
  2. Android SDK下载和更新失败的解决方法!!!
  3. Android studioError:(13, 0) Gradle DSL method not found: 'an
  4. android字体加粗的方法
  5. android中各种图标尺寸以及多分辨率支持方法
  6. Android的网络抓包工具Tcpdump
  7. android 7.0 系统关闭彩信过CTA测试的方法

随机推荐

  1. Android(安卓)Developers:传感器概述
  2. Cobra Tag + Android(安卓)手机帮你找东
  3. 分享 Ionic 开发 Hybrid App 中遇到的问
  4. 让我的头像圆起来--Android之圆头像 .
  5. Android极光推送区分测试正式环境详解
  6. Android(安卓)高效聚焦方案:计算图像模糊
  7. android线程 Handler Message Queue Asyn
  8. Andorid客户端更新,7大改进等你体验~
  9. 这一年半以来,关于 Android,我都写了些什么
  10. Android实现一个天气界面竟然如此简单?