android 5.1 Ethernet开发相关

android5.0以上的系统自带了ethernet service,默认开机就会启动,默认ip获取方式是动态分配。开发中,有时需要用到非公开的API,在以前,一般是通过反射去调用隐藏的API,但是这样就会存在性能隐患。首先将 framework.jar 导入到 Android Studio 中,以去掉反射。

  1. 取到系统源码的framework.jar 。路径:

     out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
    

改名得到framework.jar。

  1. 把 framework.jar 放到 app 模块的 libs 目录下, 依次打开 File –> Project Structure –> Modules 中找到 app ,在右边选择 Dependencies 选项卡,点击左下角的 + 按钮,选择 File dependency ,在弹出的 Select Path 窗口中选择 libs 中的 framework.jar

  2. 在新增的 Dependencies 记录的右边,将 Compile 修改为 Provided ,点击 OK 保存修改,Provided 的作用是只参与编译,但不打包到apk中

  3. 修改根目录下的build.prop文件

     allprojects {
         repositories {
             jcenter()
                    }
     //添加以下代码,使framework-base.jar包编译先于android.jar
     gradle.projectsEvaluated {
         tasks.withType(JavaCompile){
             options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\framework-base.jar')
         }
        }
     }
    

以太网源码流程

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

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

配置完成以后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);

android5.1 增加ethernet设置(DHCP与Static ip)

你可能感兴趣的:(android 5.1 Ethernet开发相关)