Android network框架分析目录
Android network框架分析之EthernetService启动流程 Android network框架分析之NetworkFactory与NetworkAgent深入分析 Android network框架分析之NetworkManagementService和netd交互深入分析(一) Android network框架分析之NetworkManagementService和netd交互深入分析(二) Android network框架分析之EthernetServiceImpl和NetworkManagementService交互深入分析 Android network框架分析之AsyncChannel原理分析以及实操演练 Android 9.0(P)适配以太网功能
Android network框架分析之EthernetServiceImpl和NetworkManagementService交互深入分析
0. 引言
??通过前面的篇章Android network框架分析之NetworkManagementService和netd交互深入分析(一)和Android network框架分析之NetworkManagementService和netd交互深入分析(二),我想小伙伴们对NetworkManagementService和Netd的交互已经很熟悉了,而上述二者之间提供的交互能力的使用者是谁呢?使用者有各种的的网络服务,譬如WIFI,Ethernet,Phone等!而我们这个系列篇章的核心是以太网框架,所以我们这里会以以太网服务为例说明怎么通过上述二者监听网络状态变化,以及设置网络状态的
注意: 本篇章演示的源码是Android 7.1,其中涉及的源码路径如下所示:
frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetNetworkFactory.java
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetService.java
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetServiceImpl.java
frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetConfigStore.java
frameworks/base/core/java/android/net/INetworkManagementEventObserver.aidl
frameworks//base/core/java/com/android/server/net/BaseNetworkObserver.java
??本篇章会以如下的两个点为核心来进行相关的分析
- 其一就是以太网如何监听NetworkManagementService传递过来的网络状态变化,当然我们从前面的篇章知道这里的NetworkManagementService也是一个二把手,其消息的最初来源于内核上报通过Netd传递给NetworkManagementService
- 其二就是以太网如何利用中介二把手NetworkManagementService来传递控制消息到Netd,从而来改变网络状态
??关于上述两个核心点之间涉及的进程通信架构图如下所示:
1. EthernetServiceImpl通过NetworkManagementService监听网络状态的变化
??通过前面的篇章Android network框架分析之NetworkFactory与NetworkAgent深入分析可知EthernetNetworkFactory类是Ethernet的核心管理类,几乎包含了Ethernet所有的网络管理操作,这其中就包括了通过NetworkManagementService监听网络状态的变化,那么我们这个章节也就从这里开始了。
1.1 EthernetNetworkFactory.start
??还是熟悉的味道,还是原来的配方。这里兜兜转转还是回到了EthernetNetworkFactory的start方法中,而在这个方法中EthernetNetworkFactory会以观察者的身份注册到NetworkManagementService中从而监听敌情,探知网络状态的变化进而做出抉择(这不是谍战片)!
class EthernetNetworkFactory {
public synchronized void start(Context context, Handler target) {
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
mNMService = INetworkManagementService.Stub.asInterface(b);
mInterfaceObserver = new InterfaceObserver();
try {
mNMService.registerObserver(mInterfaceObserver);
} catch (RemoteException e) {
Log.e(TAG, "Could not register InterfaceObserver " + e);
}
}
??这里可以看到在start方法中实例化了InterfaceObserver对象mInterfaceObserver,然后将该对象作为观察者通过远程Binder调用registerObserver将其注册到NetworkManagementService中,非常典型的观察者设计模式,而这里的我们需要重点关注的就是InterfaceObserver类了。
1.2 InterfaceObserver
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);
}
}
??InterfaceObserver精简无比,继承BaseNetworkObserver 然后重写了感兴趣的几个方法,相关方法如下:
- interfaceLinkStateChanged(),网络接口状态改变通知
- interfaceAdded(),网络模块的添加,这里我们说的是以太网,那肯定是eth类型的了譬如eth0阿等
- interfaceRemoved(),网络模块的删除,这里我们说的是以太网,那肯定是eth类型的了譬如eth0阿等
1.3 BaseNetworkObserver
public class BaseNetworkObserver extends INetworkManagementEventObserver.Stub {
@Override
public void interfaceStatusChanged(String iface, boolean up) {
}
@Override
public void interfaceRemoved(String iface) {
}
@Override
public void addressUpdated(String iface, LinkAddress address) {
}
@Override
public void addressRemoved(String iface, LinkAddress address) {
}
@Override
public void interfaceLinkStateChanged(String iface, boolean up) {
}
@Override
public void interfaceAdded(String iface) {
}
@Override
public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
}
@Override
public void interfaceMessageRecevied(String message) {
}
@Override
public void limitReached(String limitName, String iface) {
}
@Override
public void interfaceDnsServerInfo(String iface, long lifetime, String[] servers) {
}
@Override
public void routeUpdated(RouteInfo route) {
}
@Override
public void routeRemoved(RouteInfo route) {
}
}
??这里可以看到BaseNetworkObserver类的父类是INetworkManagementEventObserver.Stub,然后其接口实现都为空,这个就需要相关子类去实现了。而这些子类实现这分别为WIFI,Ethernet,Phone等然后根据自己的特点实现自己感兴趣的接口。而这里INetworkManagementEventObserver.Stub大伙一看,就应该知道这个牵涉到了aidl的Binder通信了!
1.4 INetworkManagementEventObserver
interface INetworkManagementEventObserver {
void interfaceStatusChanged(String iface, boolean up);
void interfaceLinkStateChanged(String iface, boolean up);
void interfaceAdded(String iface);
void interfaceRemoved(String iface);
void addressUpdated(String iface, in LinkAddress address);
void addressRemoved(String iface, in LinkAddress address);
void limitReached(String limitName, String iface);
void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos);
void interfaceMessageRecevied(String message);
void interfaceDnsServerInfo(String iface, long lifetime, in String[] servers);
void routeUpdated(in RouteInfo route);
void routeRemoved(in RouteInfo route);
??这里的INetworkManagementEventObserver是一个adil文件的接口类,然后在Android源码变一下生成的Java文件如下所示,而前面的BaseNetworkObserver即它服务端的实现者。
package android.net;
public interface INetworkManagementEventObserver extends android.os.IInterface {
public static abstract class Stub extends android.os.Binder implements
android.net.INetworkManagementEventObserver {
private static final java.lang.String DESCRIPTOR = "android.net.INetworkManagementEventObserver";
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
public static android.net.INetworkManagementEventObserver asInterface(
android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof android.net.INetworkManagementEventObserver))) {
return ((android.net.INetworkManagementEventObserver) iin);
}
return new android.net.INetworkManagementEventObserver.Stub.Proxy(
obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data,
android.os.Parcel reply, int flags)
throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_interfaceStatusChanged: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
boolean _arg1;
_arg1 = (0 != data.readInt());
this.interfaceStatusChanged(_arg0, _arg1);
reply.writeNoException();
return true;
}
case TRANSACTION_interfaceLinkStateChanged: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
boolean _arg1;
_arg1 = (0 != data.readInt());
this.interfaceLinkStateChanged(_arg0, _arg1);
reply.writeNoException();
return true;
}
case TRANSACTION_interfaceAdded: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
this.interfaceAdded(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_interfaceRemoved: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
this.interfaceRemoved(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_addressUpdated: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
android.net.LinkAddress _arg1;
if ((0 != data.readInt())) {
_arg1 = android.net.LinkAddress.CREATOR
.createFromParcel(data);
} else {
_arg1 = null;
}
this.addressUpdated(_arg0, _arg1);
reply.writeNoException();
return true;
}
case TRANSACTION_addressRemoved: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
android.net.LinkAddress _arg1;
if ((0 != data.readInt())) {
_arg1 = android.net.LinkAddress.CREATOR
.createFromParcel(data);
} else {
_arg1 = null;
}
this.addressRemoved(_arg0, _arg1);
reply.writeNoException();
return true;
}
case TRANSACTION_limitReached: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
java.lang.String _arg1;
_arg1 = data.readString();
this.limitReached(_arg0, _arg1);
reply.writeNoException();
return true;
}
case TRANSACTION_interfaceClassDataActivityChanged: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
boolean _arg1;
_arg1 = (0 != data.readInt());
long _arg2;
_arg2 = data.readLong();
this.interfaceClassDataActivityChanged(_arg0, _arg1, _arg2);
reply.writeNoException();
return true;
}
case TRANSACTION_interfaceMessageRecevied: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
this.interfaceMessageRecevied(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_interfaceDnsServerInfo: {
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
long _arg1;
_arg1 = data.readLong();
java.lang.String[] _arg2;
_arg2 = data.createStringArray();
this.interfaceDnsServerInfo(_arg0, _arg1, _arg2);
reply.writeNoException();
return true;
}
case TRANSACTION_routeUpdated: {
data.enforceInterface(DESCRIPTOR);
android.net.RouteInfo _arg0;
if ((0 != data.readInt())) {
_arg0 = android.net.RouteInfo.CREATOR
.createFromParcel(data);
} else {
_arg0 = null;
}
this.routeUpdated(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_routeRemoved: {
data.enforceInterface(DESCRIPTOR);
android.net.RouteInfo _arg0;
if ((0 != data.readInt())) {
_arg0 = android.net.RouteInfo.CREATOR
.createFromParcel(data);
} else {
_arg0 = null;
}
this.routeRemoved(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements
android.net.INetworkManagementEventObserver {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public void interfaceStatusChanged(java.lang.String iface,
boolean up) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface);
_data.writeInt(((up) ? (1) : (0)));
mRemote.transact(Stub.TRANSACTION_interfaceStatusChanged,
_data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void interfaceLinkStateChanged(java.lang.String iface,
boolean up) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface);
_data.writeInt(((up) ? (1) : (0)));
mRemote.transact(
Stub.TRANSACTION_interfaceLinkStateChanged, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void interfaceAdded(java.lang.String iface)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface);
mRemote.transact(Stub.TRANSACTION_interfaceAdded, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void interfaceRemoved(java.lang.String iface)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface);
mRemote.transact(Stub.TRANSACTION_interfaceRemoved, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void addressUpdated(java.lang.String iface,
android.net.LinkAddress address)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface);
if ((address != null)) {
_data.writeInt(1);
address.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_addressUpdated, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void addressRemoved(java.lang.String iface,
android.net.LinkAddress address)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface);
if ((address != null)) {
_data.writeInt(1);
address.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_addressRemoved, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void limitReached(java.lang.String limitName,
java.lang.String iface) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(limitName);
_data.writeString(iface);
mRemote.transact(Stub.TRANSACTION_limitReached, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void interfaceClassDataActivityChanged(
java.lang.String label, boolean active, long tsNanos)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(label);
_data.writeInt(((active) ? (1) : (0)));
_data.writeLong(tsNanos);
mRemote.transact(
Stub.TRANSACTION_interfaceClassDataActivityChanged,
_data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void interfaceMessageRecevied(java.lang.String message)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(message);
mRemote.transact(Stub.TRANSACTION_interfaceMessageRecevied,
_data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void interfaceDnsServerInfo(java.lang.String iface,
long lifetime, java.lang.String[] servers)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface);
_data.writeLong(lifetime);
_data.writeStringArray(servers);
mRemote.transact(Stub.TRANSACTION_interfaceDnsServerInfo,
_data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void routeUpdated(android.net.RouteInfo route)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((route != null)) {
_data.writeInt(1);
route.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_routeUpdated, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void routeRemoved(android.net.RouteInfo route)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((route != null)) {
_data.writeInt(1);
route.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_routeRemoved, _data,
_reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_interfaceStatusChanged = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_interfaceLinkStateChanged = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_interfaceAdded = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_interfaceRemoved = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_addressUpdated = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_addressRemoved = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
static final int TRANSACTION_limitReached = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
static final int TRANSACTION_interfaceClassDataActivityChanged = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
static final int TRANSACTION_interfaceMessageRecevied = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
static final int TRANSACTION_interfaceDnsServerInfo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 9);
static final int TRANSACTION_routeUpdated = (android.os.IBinder.FIRST_CALL_TRANSACTION + 10);
static final int TRANSACTION_routeRemoved = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11);
}
public void interfaceStatusChanged(java.lang.String iface, boolean up)
throws android.os.RemoteException;
public void interfaceLinkStateChanged(java.lang.String iface, boolean up)
throws android.os.RemoteException;
public void interfaceAdded(java.lang.String iface)
throws android.os.RemoteException;
public void interfaceRemoved(java.lang.String iface)
throws android.os.RemoteException;
public void addressUpdated(java.lang.String iface,
android.net.LinkAddress address) throws android.os.RemoteException;
public void addressRemoved(java.lang.String iface,
android.net.LinkAddress address) throws android.os.RemoteException;
public void limitReached(java.lang.String limitName, java.lang.String iface)
throws android.os.RemoteException;
public void interfaceClassDataActivityChanged(java.lang.String label,
boolean active, long tsNanos) throws android.os.RemoteException;
public void interfaceMessageRecevied(java.lang.String message)
throws android.os.RemoteException;
public void interfaceDnsServerInfo(java.lang.String iface, long lifetime,
java.lang.String[] servers) throws android.os.RemoteException;
public void routeUpdated(android.net.RouteInfo route)
throws android.os.RemoteException;
public void routeRemoved(android.net.RouteInfo route)
throws android.os.RemoteException;
}
1.5 NetworkManagementService.registerObserver
??让我们重返章节1.1,继续分析以太网观察者注册流程如下:
mInterfaceObserver = new InterfaceObserver();
try {
mNMService.registerObserver(mInterfaceObserver);
} catch (RemoteException e) {
Log.e(TAG, "Could not register InterfaceObserver " + e);
}
??这里我们可以看到该流程将会通过Binder通信远程调用NetworkManagementService的方法registerObserver,至于Binder间的传输流程这里就分析了,总之会调用到NetworkManagementService的registerObserver方法中,该方法的实现如下:
public void registerObserver(INetworkManagementEventObserver observer) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
mObservers.register(observer);
}
private void notifyInterfaceAdded(String iface) {
final int length = mObservers.beginBroadcast();
try {
for (int i = 0; i < length; i++) {
try {
mObservers.getBroadcastItem(i).interfaceAdded(iface);
} catch (RemoteException | RuntimeException e) {
}
}
} finally {
mObservers.finishBroadcast();
}
}
??到这里小伙伴们应该非常熟悉了吗,NMService接收到Netd传递过来的消息,然后通过注册的观察者将相关信息广播出去,当然这里的观察者也包括我们的以太网络。这里有一点需要注意的是通过远程Binder传递过来的INetworkManagementEventObserver是的Biner代理端,所以在NMService接收到消息后然后可以通过该代理端将消息端传递到以太网服务端。
??这里小伙伴们有没有一个疑问,EthernetServiceImpl和NetworkManagementService都是system_server同一个进程中,注册观察者接口为啥搞得这么复杂还要牵涉到aidl的远程调用呢?是的EthernetServiceImpl和NetworkManagementService是在同一个进程者,但是其它的网络实现者Phone等都是在其它的进程中,所以必须设计一种可以跨进程通信的观察者接口。各位小伙伴应该能理解清楚了!
1.6 EthernetServiceImpl通过NetworkManagementService监听网络状态的变化小结
??关于EthernetServiceImpl通过NetworkManagementService监听网络状态到这里就分析完毕了,如果小伙伴们还有什么疑问或者其中牵涉的过程有不清楚的,建议参考下述的时序图重新撸一遍,如下:
2. EthernetServiceImpl通过NetworkManagementService修改网络状态
??我们知道网络间的传递通常是双向的,而我们的EthernetServiceImpl和NetworkManagementService也是如此,在前面的章节中我们分析了EthernetServiceImpl怎么通过NetworkManagementService监听网络状态的改变,而在这个章节我们将要分析EthernetServiceImpl怎么通过NetworkManagementService来改变网络状态。这里我们以卸载以太网络模块为例。
2.1 EthernetNetworkFactory.setInterfaceDown
??通过前面的博客Android network框架分析之NetworkFactory与NetworkAgent深入分析可知EthernetServiceImpl是一个甩手掌柜,基本所有的事情都委托给了EthernetNetworkFactory来处理。所以吗,还是得EthernetNetworkFactory亲力亲为。
public boolean setInterfaceDown() {
try {
if(!TextUtils.isEmpty(mIface)) {
mNMService.setInterfaceDown(mIface);
return true;
} else {
Log.e(TAG,"mIface is null");
}
} catch (Exception e) {
Log.e(TAG, "Error downing interface " + mIface + ": " + e);
}
return false;
}
??这里非常简单主要是通过BInder远程调用NMService无法的setInterfaceDown方法,该方法类似于执行如下命令:
ifconfig eth0 down
2.2 NetworkManagementService.setInterfaceDown
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();
}
}
@Override
public void setInterfaceDown(String iface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
ifcg.setInterfaceDown();
setInterfaceConfig(iface, ifcg);
}
??好吗,到这个地方各位小伙伴们应该又比较熟悉了,在前面的文章Android network框架分析之NetworkManagementService和netd交互深入分析(二)讲述到了NMService将会借助NativeDaemonConnector实现和Netd的通信,然后将控制命令传递到合适的驱动处理。
2.3 EthernetServiceImpl通过NetworkManagementService修改网络状态小结
??好啦,EthernetServiceImpl通过NetworkManagementService修改网络状态也分析over了,如果小伙伴们还有什么疑问或者其中牵涉的过程有不清楚的,建议参考下述的时序图重新撸一遍,如下:
3. 小结
??好了到这里Android网络框架情景分析之NetworkManagementService和Netd交互深入分析三重奏:
??到此就全部分析完成了,通过上述三篇文章我想小伙伴们对于Android网络框架中牵涉到的各种网络状态的控制,网络状态的监控应该非常的清晰了。
??是时候说再见了,各位江山不改绿水长流,江湖见!
|