NetworkManagementService介绍
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                NetworkManagementService介绍
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                本文為《深入理解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 purposesmFgHandler = 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對象就是 mConnectormThread = new Thread(mConnector, NETD_TAG);mDaemonHandler = new Handler(FgThread.get().getLooper());mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,mDaemonHandler.getLooper()) {@Overridepublic 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 {@Overridepublic 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() {@Overridepublic void run() {prepareNativeDaemon();}});}}@Overridepublic 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 是否支持 bandwidthcontrolfinal 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_enabledSystemProperties.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());}
 
 
    @Overridepublic void setFirewallEnabled(boolean enabled) {enforceSystemUid();try {//發送firewall相關的Command給 NetdmConnector.execute("firewall", enabled ? "enable" : "disable");mFirewallEnabled = enabled;} catch (NativeDaemonConnectorException e) {throw e.rethrowAsParcelableException();}}
總結
以上是生活随笔為你收集整理的NetworkManagementService介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: GO Negotiation流程分析
 - 下一篇: Linux Wi-Fi 编程API介绍