android5.0以上的系统自带了ethernet service,默认开机就会启动,默认ip获取方式是动态分配。开发中,有时需要用到非公开的API,在以前,一般是通过反射去调用隐藏的API,但是这样就会存在性能隐患。首先将 framework.jar 导入到 Android Studio 中,以去掉反射。
-
取到系统源码的framework.jar 。路径:
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
改名得到framework.jar。
把 framework.jar 放到 app 模块的 libs 目录下, 依次打开 File –> Project Structure –> Modules 中找到 app ,在右边选择 Dependencies 选项卡,点击左下角的 + 按钮,选择 File dependency ,在弹出的 Select Path 窗口中选择 libs 中的 framework.jar
在新增的 Dependencies 记录的右边,将 Compile 修改为 Provided ,点击 OK 保存修改,Provided 的作用是只参与编译,但不打包到apk中
-
修改根目录下的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)