logcat -s TCL_EthernetManager EthernetManager EthernetService EthernetServiceImpl EthernetNetworkFactory EthernetConfigStore TCL_EthernetDevInfo CommandListener ConnectivityService NetworkSettingsActivity Ethernetd dhcpcd NetworkMonitorNetworkAgentInfo NetworkManagementService NetdConnector NativeDaemonConnector Guide NetworkMonitorNetworkAgentInfo
一、启动流程
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer { private static final String ETHERNET_SERVICE_CLASS = "com.android.server.ethernet.EthernetService"; public static void main(String[] args) { new SystemServer().run(); } private void run() { startOtherServices(); } private void startOtherServices() { if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)) { mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS); } } }frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetService.java
public final class EthernetService extends SystemService { private static final String TAG = "EthernetService"; final EthernetServiceImpl mImpl; public EthernetService(Context context) { super(context); mImpl = new EthernetServiceImpl(context); } @Override public void onStart() { Log.i(TAG, "Registering service " + Context.ETHERNET_SERVICE); publishBinderService(Context.ETHERNET_SERVICE, mImpl); } @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { mImpl.start(); } } }frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java
public class EthernetServiceImpl extends IEthernetManager.Stub { 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); IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); mNMService = INetworkManagementService.Stub.asInterface(b); mTracker = new EthernetNetworkFactory(); } public void start() { mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); HandlerThread handlerThread = new HandlerThread("EthernetServiceThread"); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mEnabled = getPersistedState(); Log.i(TAG, "Ethernet Persisted Enabled " + mEnabled); setState(mEnabled); //重要 } public synchronized void setState(int state) { enforceChangePermission(); Log.i(TAG, "setState from mState=" + mState + " to state=" + state); if (mState != state) { mState = state; if (state == EthernetManager.ETHERNET_STATE_DISABLED) { setPersistedState(EthernetManager.ETHERNET_STATE_DISABLED); mTracker.stopInterface(); mStarted.set(false); } else { setPersistedState(EthernetManager.ETHERNET_STATE_ENABLED); mTracker.stop(); mTracker.start(mContext, mHandler); mStarted.set(true); } } } }frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
class EthernetNetworkFactory { EthernetNetworkFactory() { mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, ""); mLinkProperties = new LinkProperties(); initNetworkCapabilities(); } public synchronized void start(Context context, Handler target) { IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); mNMService = INetworkManagementService.Stub.asInterface(b); mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE); mFactory = new LocalNetworkFactory(NETWORK_TYPE, context, target.getLooper()); mFactory.setCapabilityFilter(mNetworkCapabilities); mFactory.setScoreFilter(-1); // this set high when we have an iface mFactory.register(); /* public void register() { if (DBG) log("Registering NetworkFactory"); if (mMessenger == null) { mMessenger = new Messenger(this); ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG); } } frameworks/base/services/core/java/com/android/server/ConnectivityService.java public void registerNetworkFactory(Messenger messenger, String name) { NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel()); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi)); } private class InternalHandler extends Handler { public void handleMessage(Message msg) { case EVENT_REGISTER_NETWORK_FACTORY: { handleRegisterNetworkFactory((NetworkFactoryInfo)msg.obj); break; } } } private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) { if (DBG) log("Got NetworkFactory Messenger for " + nfi.name); mNetworkFactoryInfos.put(nfi.messenger, nfi); nfi.asyncChannel.connect(mContext, mTrackerHandler, nfi.messenger); } */ mInterfaceObserver = new InterfaceObserver(); try { mNMService.registerObserver(mInterfaceObserver); } catch (RemoteException e) { Log.e(TAG, "Could not register InterfaceObserver " + e); } updateInterfaceState(iface, true); //注册 } private void updateInterfaceState(String iface, boolean up) { updateAgent(); mFactory.setScoreFilter(up ? NETWORK_SCORE : -1); //设置scroe值;这个是网络优先级判断依据 } public void updateAgent() { mNetworkAgent.sendNetworkInfo(mNetworkInfo); } }2.ETHERNET监听NETD进程的socket
init.rc
service netd /system/bin/netd class main socket netd stream 0660 root system socket dnsproxyd stream 0660 root inet socket mdns stream 0660 root system socket fwmarkd stream 0660 root inet
frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
public static NetworkManagementService create(Context context) throws InterruptedException { return create(context, NETD_SOCKET_NAME); /* private static final String NETD_SOCKET_NAME = "netd"; */ } private NetworkManagementService(Context context, String socket) { mConnector = new NativeDaemonConnector( new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl, FgThread.get().getLooper()); /* frameworks/base/services/core/java/com/android/server/NativeDaemonConnector.java public void run() { mCallbackHandler = new Handler(mLooper, this); while (true) { try { listenToSocket(); } catch (Exception e) { loge("Error in NativeDaemonConnector: " + e); SystemClock.sleep(5000); } } } private void listenToSocket() throws IOException { LocalSocketAddress address = determineSocketAddress(); mCallbackHandler.sendMessage(); } public boolean handleMessage(Message msg) { mCallbacks.onEvent } */ } private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { public boolean onEvent(int code, String raw, String[] cooked) { notifyInterfaceAdded(cooked[3]); ...... notifyInterfaceRemoved(cooked[3]); ...... notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up")); ...... notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up")); } private void notifyInterfaceLinkStateChanged(String iface, boolean up) { mObservers.getBroadcastItem(i).interfaceLinkStateChanged(iface, up); } }frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
private class InterfaceObserver extends BaseNetworkObserver { public void interfaceLinkStateChanged(String iface, boolean up) { updateInterfaceState(iface, up); } } private void updateInterfaceState(String iface, boolean up) { mFactory.setScoreFilter(up ? NETWORK_SCORE : -1); }frameworks/base/core/java/android/net/NetworkFactory.java
public void setScoreFilter(int score) { sendMessage(obtainMessage(CMD_SET_SCORE, score, 0)); } public void handleMessage(Message msg) { case CMD_SET_SCORE: { handleSetScore(msg.arg1); break; } } private void handleSetScore(int score) { mScore = score; evalRequests(); } private void evalRequests() { for (int i = 0; i < mNetworkRequests.size(); i++) { NetworkRequestInfo n = mNetworkRequests.valueAt(i); evalRequest(n); } } private void evalRequest(NetworkRequestInfo n) { needNetworkFor(n.request, n.score); } protected void needNetworkFor(NetworkRequest networkRequest, int score) { if (++mRefCount == 1) startNetwork(); }frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
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() { } } public void onRequestNetwork() { Thread dhcpThread = new Thread(new Runnable() { public void run() { DhcpResults dhcpResults = new DhcpResults(); //DHCP相关 if (!NetworkUtils.runDhcp(mIface, dhcpResults)) { /* frameworks/base/core/java/android/net/NetworkUtils.java public native static boolean runDhcp(String interfaceName, DhcpResults dhcpResults); frameworks/base/core/jni/android_net_NetUtils.cp static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info) { return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false); } static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname, jobject dhcpResults, bool renew) { if (renew) { result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength, dns, server, &lease, vendorInfo, domains, mtu); } else { result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength, dns, server, &lease, vendorInfo, domains, mtu); } } system/core/libnetutils/dhcp_utils.c 见博文:《Android系统DHCP问题》 上处DHCP Client和DHCP server(system/bin/dhcpd进程)通过property_get/set 共享内存来共享信息 */ Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError()); // set our score lower than any network could go // so we get dropped. mFactory.setScoreFilter(-1); return; } mNetworkAgent = new NetworkAgent(mFactory.getLooper(), mContext, NETWORK_TYPE, mNetworkInfo, mNetworkCapabilities, mLinkProperties, NETWORK_SCORE) } }); dhcpThread.start(); }
三、项目问题
应用程序调用关键API
public void updateDevInfo(EthernetDevInfo info);
配置完成以后ConnectivityService向EthernetManager发送CONNECTIVITY_ACTION_IMMEDIATE的广播;EthernetManager接收到该广播以后向应用程序发送ETHERNET_INTERFACE_CONF_CHANGED广播。否则;应用程序将TIMEOUT。
public static final String EXTRA_ETHERNET_STATE = "ETHERNET_state"; public static final String ETHERNET_INTERFACE_CONF_CHANGED = "android.net.ethernet.ETHERNET_INTERFACE_CONF_CHANGED"; //add by tank private void sendEthBroadcast(String action, boolean state) { String bootStr = SystemProperties.get("sys.boot_completed"); Log.d(TAG, "sendEthBroadcast -->: " + bootStr); if(bootStr.equals("1")) { //boot complete Intent intent = new Intent(action); intent.putExtra(EXTRA_ETHERNET_STATE, state); Log.d(TAG, "sendEthBroadcast --> action= " + action + " state=" + state); mContext.sendBroadcast(intent); } } //连接成功调用如下: sendEthBroadcast(ETHERNET_INTERFACE_CONF_CHANGED, true); //连接失败调用如下: sendEthBroadcast(ETHERNET_INTERFACE_CONF_CHANGED, false);
1.手动配置IP后子网掩码错误,以及子网掩码在应用不显示问题
原因:向上层应用提供信息有误
2.手动配置IP提示网关错误,以及网关获取错误问题
原因:同上
3.自动获取IP地址速度慢
原因:应用程序在等待ConnectivityService的广播通过EthernetManager发送的广播