NetworkManagementService介绍
来源:互联网 发布:国外大数据产业园 编辑:程序博客网 时间:2024/05/08 07:20
本文为《深入理解Android Wi-Fi、NFC和GPS卷》读书笔记,Android源码为Android 5.1
NetworkManagementService(以后简称 NMService)将通过 netd socket 和 Netd 交互:
android-5.1/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {.....//其他Service 的创建及相关处理 if (!disableNetwork) { try { Slog.i(TAG, "NetworkManagement Service"); networkManagement = NetworkManagementService.create(context); ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement); } catch (Throwable e) { reportWtf("starting NetworkManagement Service", e); } }...... try { if (networkManagementF != null) networkManagementF.systemReady(); } catch (Throwable e) { reportWtf("making Network Managment Service ready", e); }......}ServerThread是Android Java Framework 的中枢,绝大部分重要 Service 都在该线程中创建,例如 ActivityManagerService、 WindowManagerService、 PackageManagerService 以及本书要介绍的 WiFiService、 WifiP2pService等。
ServerThread 中和 NMService 相关的重要知识点仅 create 和 systemReady 两个函数:
android-5.1/frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
static NetworkManagementService create(Context context, String socket) throws InterruptedException {//创建一个 NMService 对象 final NetworkManagementService service = new NetworkManagementService(context, socket); final CountDownLatch connectedSignal = service.mConnectedSignal; if (DBG) Slog.d(TAG, "Creating NetworkManagementService"); service.mThread.start();//启动 NMService 中的一个线程 if (DBG) Slog.d(TAG, "Awaiting socket connection");//connectedSignal 用于等待某个事情的发生。此处是等待 mThread 完成初始化工作 connectedSignal.await(); if (DBG) Slog.d(TAG, "Connected"); return service; }create 函数主要工作是创建一个 NMService 对象并启动其中一个线程。 create 返回前需要确保 mThread 线程完成初始化工作。下面来看构造函数:
android-5.1/frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
private NetworkManagementService(Context context, String socket) { mContext = context; // make sure this is on the same looper as our NativeDaemonConnector for sync purposes mFgHandler = new Handler(FgThread.get().getLooper());//对模拟器的处理 if ("simulator".equals(SystemProperties.get("ro.product.device"))) { mConnector = null; mThread = null; mDaemonHandler = null; mPhoneStateListener = null; return; } // Don't need this wake lock, since we now have a time stamp for when // the network actually went inactive. (It might be nice to still do this, // but I don't want to do it through the power manager because that pollutes the // battery stats history with pointless noise.) //PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = null; //pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NETD_TAG);//NativeDaemonConnector 是Java Framework 中一个特别的类,它用于连接指定的 socket,并发送和接收 socket 数据。//netd 参数代表目标 socket。 NetdCallbackReceiver 为具体的 socket 连接及消息处理对象。//1.当Netd连接成功后, NetdCallbackReceiver 的 onDaemonConnected 函数将被调用。//2.当收到来自 Netd 的数据后, NetdCallbackReceiver 的 onEvent 函数将被调用。 mConnector = new NativeDaemonConnector( new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl, FgThread.get().getLooper());//创建一个线程,其runnable对象就是 mConnector mThread = new Thread(mConnector, NETD_TAG); mDaemonHandler = new Handler(FgThread.get().getLooper()); mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mDaemonHandler.getLooper()) { @Override public void onDataConnectionRealTimeInfoChanged( DataConnectionRealTimeInfo dcRtInfo) { if (DBG) Slog.d(TAG, "onDataConnectionRealTimeInfoChanged: " + dcRtInfo); notifyInterfaceClassActivity(ConnectivityManager.TYPE_MOBILE, dcRtInfo.getDcPowerState(), dcRtInfo.getTime(), true); } }; TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); if (tm != null) { tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO); } // Add ourself to the Watchdog monitors.//把自己添加到watchdog中的监控队列中。这样 NMService 将受到 watchdog 的监控, 一旦 NMService 出现异常, watchdog 将自杀以重启 Android Java World。 Watchdog.getInstance().addMonitor(this); }上述代码最重要的是 NetdCallbackReceiver :
android-5.1/frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { @Override public void onDaemonConnected() { // event is dispatched from internal NDC thread, so we prepare the // daemon back on main thread. if (mConnectedSignal != null) {//通知 NMService 构造函数中的 connectedSignal.await() 返回 mConnectedSignal.countDown(); mConnectedSignal = null; } else { mFgHandler.post(new Runnable() { @Override public void run() { prepareNativeDaemon(); } }); } } @Override public boolean onCheckHoldWakeLock(int code) { return code == NetdResponseCode.InterfaceClassActivity; } @Override//处理来自 Netd 的消息 public boolean onEvent(int code, String raw, String[] cooked) { String errorMessage = String.format("Invalid event from daemon (%s)", raw); switch (code) { case NetdResponseCode.InterfaceChange://对应 InterfaceCmd /* * a network interface change occured * Format: "NNN Iface added <name>" * "NNN Iface removed <name>" * "NNN Iface changed <name> <up/down>" * "NNN Iface linkstatus <name> <up/down>" */ if (cooked.length < 4 || !cooked[1].equals("Iface")) { throw new IllegalStateException(errorMessage); } if (cooked[2].equals("added")) { notifyInterfaceAdded(cooked[3]); return true; } else if (cooked[2].equals("removed")) { notifyInterfaceRemoved(cooked[3]); return true; } else if (cooked[2].equals("changed") && cooked.length == 5) { notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up")); return true; } else if (cooked[2].equals("linkstate") && cooked.length == 5) { notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up")); return true; } throw new IllegalStateException(errorMessage); // break; case NetdResponseCode.BandwidthControl://对应 BandwidthControlCmd /* * Bandwidth control needs some attention * Format: "NNN limit alert <alertName> <ifaceName>" */ if (cooked.length < 5 || !cooked[1].equals("limit")) { throw new IllegalStateException(errorMessage); } if (cooked[2].equals("alert")) { notifyLimitReached(cooked[3], cooked[4]); return true; } throw new IllegalStateException(errorMessage); // break; case NetdResponseCode.InterfaceClassActivity://和IdletimerCmd有关 /* * An network interface class state changed (active/idle) * Format: "NNN IfaceClass <active/idle> <label>" */ if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) { throw new IllegalStateException(errorMessage); } long timestampNanos = 0; if (cooked.length == 5) { try { timestampNanos = Long.parseLong(cooked[4]); } catch(NumberFormatException ne) {} } else { timestampNanos = SystemClock.elapsedRealtimeNanos(); } boolean isActive = cooked[2].equals("active"); notifyInterfaceClassActivity(Integer.parseInt(cooked[3]), isActive ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, timestampNanos, false); return true; // break; case NetdResponseCode.InterfaceAddressChange: /* * A network address change occurred * Format: "NNN Address updated <addr> <iface> <flags> <scope>" * "NNN Address removed <addr> <iface> <flags> <scope>" */ if (cooked.length < 7 || !cooked[1].equals("Address")) { throw new IllegalStateException(errorMessage); } String iface = cooked[4]; LinkAddress address; try { int flags = Integer.parseInt(cooked[5]); int scope = Integer.parseInt(cooked[6]); address = new LinkAddress(cooked[3], flags, scope); } catch(NumberFormatException e) { // Non-numeric lifetime or scope. throw new IllegalStateException(errorMessage, e); } catch(IllegalArgumentException e) { // Malformed/invalid IP address. throw new IllegalStateException(errorMessage, e); } if (cooked[2].equals("updated")) { notifyAddressUpdated(iface, address); } else { notifyAddressRemoved(iface, address); } return true; // break; case NetdResponseCode.InterfaceDnsServerInfo: /* * Information about available DNS servers has been received. * Format: "NNN DnsInfo servers <interface> <lifetime> <servers>" */ long lifetime; // Actually a 32-bit unsigned integer. if (cooked.length == 6 && cooked[1].equals("DnsInfo") && cooked[2].equals("servers")) { try { lifetime = Long.parseLong(cooked[4]); } catch (NumberFormatException e) { throw new IllegalStateException(errorMessage); } String[] servers = cooked[5].split(","); notifyInterfaceDnsServerInfo(cooked[3], lifetime, servers); } return true; // break; case NetdResponseCode.RouteChange: /* * A route has been updated or removed. * Format: "NNN Route <updated|removed> <dst> [via <gateway] [dev <iface>]" */ if (!cooked[1].equals("Route") || cooked.length < 6) { throw new IllegalStateException(errorMessage); } String via = null; String dev = null; boolean valid = true; for (int i = 4; (i + 1) < cooked.length && valid; i += 2) { if (cooked[i].equals("dev")) { if (dev == null) { dev = cooked[i+1]; } else { valid = false; // Duplicate interface. } } else if (cooked[i].equals("via")) { if (via == null) { via = cooked[i+1]; } else { valid = false; // Duplicate gateway. } } else { valid = false; // Unknown syntax. } } if (valid) { try { // InetAddress.parseNumericAddress(null) inexplicably returns ::1. InetAddress gateway = null; if (via != null) gateway = InetAddress.parseNumericAddress(via); RouteInfo route = new RouteInfo(new IpPrefix(cooked[3]), gateway, dev); notifyRouteChange(cooked[2], route); return true; } catch (IllegalArgumentException e) {} } throw new IllegalStateException(errorMessage); // break; default: break; } return false; } }systemReady 函数详解:
android-5.1/frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
public void systemReady() { prepareNativeDaemon(); if (DBG) Slog.d(TAG, "Prepared"); }prepareNativeDaemon 用于将系统中一些与带宽控制、防火墙相关的规则发送给 Netd 去执行:
android-5.1/frameworks/base/services/core/java/com/android/server/NetworkManagementService.java
private void prepareNativeDaemon() { mBandwidthControlEnabled = false; // only enable bandwidth control when support exists//判断 kernel 是否支持 bandwidthcontrol final boolean hasKernelSupport = new File("/proc/net/xt_qtaguid/ctrl").exists(); if (hasKernelSupport) { Slog.d(TAG, "enabling bandwidth control"); try { mConnector.execute("bandwidth", "enable");//使能 bandwidth 功能 mBandwidthControlEnabled = true; } catch (NativeDaemonConnectorException e) { Log.wtf(TAG, "problem enabling bandwidth controls", e); } } else { Slog.d(TAG, "not enabling bandwidth control"); }//设置 Android 系统属性 net.qtaguid_enabled SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0"); if (mBandwidthControlEnabled) { try { getBatteryStats().noteNetworkStatsEnabled(); } catch (RemoteException e) { } } // push any existing quota or UID rules//设置 Bandwidth 规则 synchronized (mQuotaLock) { int size = mActiveQuotas.size(); if (size > 0) { Slog.d(TAG, "ushing " + size + " active quota rules");//mActiveQuotas 保存了每个 Interface 的配额设置 final HashMap<String, Long> activeQuotas = mActiveQuotas; mActiveQuotas = Maps.newHashMap(); for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) { setInterfaceQuota(entry.getKey(), entry.getValue()); } } size = mActiveAlerts.size(); if (size > 0) { Slog.d(TAG, "pushing " + size + " active alert rules"); final HashMap<String, Long> activeAlerts = mActiveAlerts; mActiveAlerts = Maps.newHashMap(); for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) { setInterfaceAlert(entry.getKey(), entry.getValue()); } } size = mUidRejectOnQuota.size(); if (size > 0) { Slog.d(TAG, "pushing " + size + " active uid rules"); final SparseBooleanArray uidRejectOnQuota = mUidRejectOnQuota; mUidRejectOnQuota = new SparseBooleanArray(); for (int i = 0; i < uidRejectOnQuota.size(); i++) { setUidNetworkRules(uidRejectOnQuota.keyAt(i), uidRejectOnQuota.valueAt(i)); } } } // TODO: Push any existing firewall state//设置防火墙规则 setFirewallEnabled(mFirewallEnabled || LockdownVpnTracker.isEnabled()); }
@Override public void setFirewallEnabled(boolean enabled) { enforceSystemUid(); try {//发送firewall相关的Command给 Netd mConnector.execute("firewall", enabled ? "enable" : "disable"); mFirewallEnabled = enabled; } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } }
0 1
- NetworkManagementService介绍
- [Android4.4]NetworkManagementService与Netd交互流程
- [android]netd与NetworkManagementService初印象
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- 介绍
- linux kernel 中断子系统之(一)-- ARM GIC 硬件
- Java5新增的同步工具
- 【C语言】求序列2/1+3/2+5/3+8/5+13/8+........前20项和。
- 矩阵乘法 之 strassen 算法
- MinHook源码阅读
- NetworkManagementService介绍
- Android Studio系列教程四--Gradle基础
- MySQL数据库分布式事务XA优缺点与改进方案
- maven打包报错Unable to locate the JavacCompiler in
- 那些年苹果与 USB 的爱恨情仇
- ubuntu下su命令认证失败的解决方法
- C语言中常用计时方法总结
- 专注于javaEE
- Ubuntu中安装配置hadoop 2.6.0并编译运行WordCount