Android 网络管理

20 篇文章 5 订阅

一、相关服务的启动

1. Netd 中创建 NETD_SERVICE 服务注册到 binder 中,在 framework 层直接获取对应的引用对象

实例:在 NetworkManagementService 中类初始化采用 create 接口,其中新建对象,调用了 connectNativeNetdService 初始化了 INetd 对象 mNetdService ,其实调用了内部类 SystemServices 的 getNetd 方法,进而调用了 NetdService 类的 get 方法,最终调用 getInstance,而到 ServiceManager 类的 getService 方法,传入了 Context.NETD_SERVICE 参数 “netd” 获取到。

2. SystemServer 中 通过 startOtherServices 首先创建了 IpConnectivityMetrics 和 NetworkWatchlistService 服务:

            t.traceBegin("IpConnectivityMetrics");
            mSystemServiceManager.startService(IP_CONNECTIVITY_METRICS_CLASS);
            t.traceEnd();

            t.traceBegin("NetworkWatchlistService");
            mSystemServiceManager.startService(NetworkWatchlistService.Lifecycle.class);
            t.traceEnd();

3. 接下来就是 ConnectivityModuleConnector 和 NetworkStackClient 的初始化:

            t.traceBegin("InitConnectivityModuleConnector");
            try {
                ConnectivityModuleConnector.getInstance().init(context);
            } catch (Throwable e) {
                reportWtf("initializing ConnectivityModuleConnector", e);
            }
            t.traceEnd();

            t.traceBegin("InitNetworkStackClient");
            try {
                NetworkStackClient.getInstance().init();
            } catch (Throwable e) {
                reportWtf("initializing NetworkStackClient", e);
            }
            t.traceEnd();

4. 重点的 NetworkManagementService 启动:

            t.traceBegin("StartNetworkManagementService");
            try {
                networkManagement = NetworkManagementService.create(context);
                ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
            } catch (Throwable e) {
                reportWtf("starting NetworkManagement Service", e);
            }
            t.traceEnd();

5. 然后是 IpSecService:

            t.traceBegin("StartIpSecService");
            try {
                ipSecService = IpSecService.create(context, networkManagement);
                ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
            } catch (Throwable e) {
                reportWtf("starting IpSec Service", e);
            }
            t.traceEnd();

6. 接下来是三个重要的 Network 相关:

            t.traceBegin("StartNetworkScoreService");
            mSystemServiceManager.startService(NetworkScoreService.Lifecycle.class);
            t.traceEnd();

            t.traceBegin("StartNetworkStatsService");
            try {
                networkStats = NetworkStatsService.create(context, networkManagement);
                ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
            } catch (Throwable e) {
                reportWtf("starting NetworkStats Service", e);
            }
            t.traceEnd();

            t.traceBegin("StartNetworkPolicyManagerService");
            try {
                networkPolicy = new NetworkPolicyManagerService(context, mActivityManagerService,
                        networkManagement);
                ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
            } catch (Throwable e) {
                reportWtf("starting NetworkPolicy Service", e);
            }
            t.traceEnd();

7. 重要的 WiFi 相关内容开始:

            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI)) {
                // Wifi Service must be started first for wifi-related services.
                t.traceBegin("StartWifi");
                mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
                t.traceEnd();
                t.traceBegin("StartWifiScanning");
                mSystemServiceManager.startService(
                        "com.android.server.wifi.scanner.WifiScanningService");
                t.traceEnd();
            }

            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI_RTT)) {
                t.traceBegin("StartRttService");
                mSystemServiceManager.startService(
                        "com.android.server.wifi.rtt.RttService");
                t.traceEnd();
            }

            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI_AWARE)) {
                t.traceBegin("StartWifiAware");
                mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
                t.traceEnd();
            }

            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI_DIRECT)) {
                t.traceBegin("StartWifiP2P");
                mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
                t.traceEnd();
            }

8. 核心的连接管理和服务发现:

            t.traceBegin("StartConnectivityService");
            // This has to be called after NetworkManagementService, NetworkStatsService
            // and NetworkPolicyManager because ConnectivityService needs to take these
            // services to initialize.
            // TODO: Dynamically load service-connectivity.jar by using startServiceFromJar.
            mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_CLASS);
            connectivity = IConnectivityManager.Stub.asInterface(
                    ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
            // TODO: Use ConnectivityManager instead of ConnectivityService.
            networkPolicy.bindConnectivityManager(connectivity);
            t.traceEnd();

            t.traceBegin("StartNsdService");
            try {
                serviceDiscovery = NsdService.create(context);
                ServiceManager.addService(
                        Context.NSD_SERVICE, serviceDiscovery);
            } catch (Throwable e) {
                reportWtf("starting Service Discovery Service", e);
            }
            t.traceEnd();

二、服务启动运行过程

1. NetworkManagementService

通过 create 静态方法创建:

    public static NetworkManagementService create(Context context) throws InterruptedException {
        return create(context, new SystemServices());
    }

进一步调用内部 create 方法,新增参数 SystemServices 对象,为其内部类对象:

    /**
     * Helper class that encapsulates NetworkManagementService dependencies and makes them
     * easier to mock in unit tests.
     */
    static class SystemServices {
        public IBinder getService(String name) {
            return ServiceManager.getService(name);
        }
        public void registerLocalService(NetworkManagementInternal nmi) {
            LocalServices.addService(NetworkManagementInternal.class, nmi);
        }
        public INetd getNetd() {
            return NetdService.get();
        }
    }

该辅助类其实就是封装了三个方法而已,继续看 create 方法:

    static NetworkManagementService create(Context context, SystemServices services)
            throws InterruptedException {
        final NetworkManagementService service =
                new NetworkManagementService(context, services);
        if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
        if (DBG) Slog.d(TAG, "Connecting native netd service");
        service.connectNativeNetdService();
        if (DBG) Slog.d(TAG, "Connected");
        return service;
    }

就是通过构造方法创建了类对象,并且将其与 Netd 服务进行连接:

    /**
     * Constructs a new NetworkManagementService instance
     *
     * @param context  Binder context for this service
     */
    private NetworkManagementService(
            Context context, SystemServices services) {
        mContext = context;
        mServices = services;

        mDaemonHandler = new Handler(FgThread.get().getLooper());

        mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();

        mServices.registerLocalService(new LocalService());

        synchronized (mTetheringStatsProviders) {
            mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd");
        }
    }

其实就是初始化了三个参数:

mNetdService 为 INetd 对象,为 netd 的 binder 服务的客户端引用;

mDaemonHandler 为 Handler 新对象,用于处理消息,在 Listener 收到回调处理请求之后通过 Handler 进行处理,发送对应的消息到消息队列,而其中的 Looper 会处理消息;

mNetdUnsolicitedEventListener 为 NetdUnsolicitedEventListener 对象,监听 netd 中的消息通知进行相应的处理,在这里直接调用了 INetd 的 registerUnsolicitedEventListener 方法注册;

mDaemonHandler = new Handler(FgThread.get().getLooper());

这里的 Looper 是怎么获取到的呢?这里采用了 FgThread,其实就是 Foreground Thread 的意思,其定义如下:

// 文件:base/services/core/java/com/android/server/FgThread.java
package com.android.server;

import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Trace;

import java.util.concurrent.Executor;

/**
 * Shared singleton foreground thread for the system.  This is a thread for regular
 * foreground service operations, which shouldn't be blocked by anything running in
 * the background.  In particular, the shared background thread could be doing
 * relatively long-running operations like saving state to disk (in addition to
 * simply being a background priority), which can cause operations scheduled on it
 * to be delayed for a user-noticeable amount of time.
 */
public final class FgThread extends ServiceThread {
    private static final long SLOW_DISPATCH_THRESHOLD_MS = 100;
    private static final long SLOW_DELIVERY_THRESHOLD_MS = 200;

    private static FgThread sInstance;
    private static Handler sHandler;
    private static HandlerExecutor sHandlerExecutor;

    private FgThread() {
        super("android.fg", android.os.Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
    }

    private static void ensureThreadLocked() {
        if (sInstance == null) {
            sInstance = new FgThread();
            sInstance.start();
            final Looper looper = sInstance.getLooper();
            looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
            looper.setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
            sHandler = new Handler(sInstance.getLooper());
            sHandlerExecutor = new HandlerExecutor(sHandler);
        }
    }

    public static FgThread get() {
        synchronized (FgThread.class) {
            ensureThreadLocked();
            return sInstance;
        }
    }

    public static Handler getHandler() {
        synchronized (FgThread.class) {
            ensureThreadLocked();
            return sHandler;
        }
    }

    public static Executor getExecutor() {
        synchronized (FgThread.class) {
            ensureThreadLocked();
            return sHandlerExecutor;
        }
    }
}

实现意图很简单,其内部定义均为静态,从而保证在进程内部唯一,而实际的创建过程发生在 ensureThreadLocked 接口中,用于确保在第一次调用过程中创建并初始化新的线程。从而在调用过程中可以直接调用该类的静态接口获取对应的内容,如上面获取到线程对应的 Looper 对象。

Looper 对象的创建在线程的 run 接口中,该接口在线程运行过程中被调用,进入实际的执行阶段:

    /**
     * Call back method that can be explicitly overridden if needed to execute some
     * setup before Looper loops.
     */
    protected void onLooperPrepared() {
    }

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

 其中执行了 Looper 类的 prepare 静态方法,在其中创建了对应的 Looper 对象:

    /** Initialize the current thread as a looper.
      * This gives you a chance to create handlers that then reference
      * this looper, before actually starting the loop. Be sure to call
      * {@link #loop()} after calling this method, and end it by calling
      * {@link #quit()}.
      */
    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

紧接着在 run 函数中调用 Looper 的 loop 接口进入循环处理消息的过程。 

mNetdUnsolicitedEventListener 是 NetdUnsolicitedEventListener 对象,继承了 INetdUnsolicitedEventListener.Stub 接口类,实现了对应的接口,它作为 binder 服务端,在这里调用了 INetd 服务的接口 registerUnsolicitedEventListener 将其进行注册:

binder::Status NetdNativeService::registerUnsolicitedEventListener(
        const android::sp<android::net::INetdUnsolicitedEventListener>& listener) {
    ENFORCE_NETWORK_STACK_PERMISSIONS();
    gCtls->eventReporter.registerUnsolEventListener(listener);
    return binder::Status::ok();
}

这里调用了 gCtrls 类的 eventReporter 成员的  registerUnsolEventListener 方法,就是 Controllers 类的 EventReporter eventReporter; 成员,EventReporter 类接口定义如下:

void EventReporter::registerUnsolEventListener(
        const android::sp<INetdUnsolicitedEventListener>& listener) {
    std::lock_guard lock(mUnsolicitedMutex);

    // Create the death listener.
    class DeathRecipient : public android::IBinder::DeathRecipient {
      public:
        DeathRecipient(EventReporter* eventReporter,
                       android::sp<INetdUnsolicitedEventListener> listener)
            : mEventReporter(eventReporter), mListener(std::move(listener)) {}
        ~DeathRecipient() override = default;
        void binderDied(const android::wp<android::IBinder>& /* who */) override {
            mEventReporter->unregisterUnsolEventListener(mListener);
        }

      private:
        EventReporter* mEventReporter;
        android::sp<INetdUnsolicitedEventListener> mListener;
    };
    android::sp<android::IBinder::DeathRecipient> deathRecipient =
            new DeathRecipient(this, listener);

    android::IInterface::asBinder(listener)->linkToDeath(deathRecipient);

    // TODO: Consider to use remote binder address as registering key
    mUnsolListenerMap.insert({listener, deathRecipient});
}

也就是将对应的信息保存起来,在后面进行相应的回调。这里是作为私有的 binder 直接传送给 netd 中的。

2.  WIFI_SERVICE_CLASS 的启动

通过 SystemServerManager 的 startService 方法启动:

mSystemServiceManager.startService(WIFI_SERVICE_CLASS);

实际进入 SystemServiceManager 中:

    /**
     * Starts a service by class name.
     *
     * @return The service instance.
     */
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass = loadClassFromLoader(className,
                this.getClass().getClassLoader());
        return startService(serviceClass);
    }

进而调用了模板函数,其中执行了 startService,以 SystemService 类为模板类:

    /**
     * Creates and starts a system service. The class must be a subclass of
     * {@link com.android.server.SystemService}.
     *
     * @param serviceClass A Java class that implements the SystemService interface.
     * @return The service instance, never null.
     * @throws RuntimeException if the service fails to start.
     */
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }

            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

先是创建了对应的 service 对象,最终的 startService 执行了两个动作,将 service 对象加入 ArrayList<SystemService> mServices 列表中,并且执行器 onStart 方法。

对象创建:

    public WifiService(Context contextBase) {
        super(contextBase);
        mWifiContext = new WifiContext(contextBase);
        WifiInjector injector = new WifiInjector(mWifiContext);
        WifiAsyncChannel channel =  new WifiAsyncChannel(TAG);
        mImpl = new WifiServiceImpl(mWifiContext, injector, channel);
    }

这里面完成了非常重要的 WifiInjector 对象的创建和初始化,并且初始化 WifiServiceImpl 类对象 mImpl,它实际完成 WifiService 的各项功能。

接下来对于 WifiService 而言执行 onStart 如下:

    @Override
    public void onStart() {
        Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
        publishBinderService(Context.WIFI_SERVICE, mImpl);
    }

这里就是讲 WIFI_SERVICE 发布或者注册到 binder 中,从而可以开始进行 WifiService 服务的获取并执行相应的操作了。

对于 WifiService 后面还执行了两个 onBootPhase 阶段操作:

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            createNotificationChannels(mWifiContext);
            mImpl.checkAndStartWifi();
        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
            mImpl.handleBootCompleted();
        }
    }

在 PHASE_SYSTEM_SERVICES_READY 阶段完成 createNotificationChannels 和 checkAndStartWifi 操作,在 PHASE_BOOT_COMPLETED 阶段完成 handleBootCompleted 操作:

createNotificationChannels:注册了三个 NotificationChannel,用于接收 NETWORK_{STATUS, ALERTS, AVAILABLE} 消息;

mImpl.checkAndStartWifi:定义了一个 api 将其用于生成 Message 对象,赋值给 callback 成员,将消息加入到 mWifiThreadRunner 的 mHandler 消息队列,delay 为 0,交给其他线程执行;ClientModeImpl 对象的 initialize 方法在这里执行,ActiveModeWarden 状态机的 start 方法也被调用,状态机开启,开始监控 WiFi 的运行状态;

mImpl.handleBootCompleted:同样通过 Message 在消息处理中执行了临时定义函数,这两步都注册了大量的消息接收过程,包括 BroadcastReceiver 和 InteneFilter;这里执行了 ClientModeImpl 的 handleBootCompleted 方法,触发其状态机内部的消息处理。

3. WifiScanningService 服务

接下来对其进行初始化:


                mSystemServiceManager.startService(
                        "com.android.server.wifi.scanner.WifiScanningService");

逻辑如上面 WifiService,首先是创建了类对象:

    public WifiScanningService(Context contextBase) {
        super(new WifiContext(contextBase));
        Log.i(TAG, "Creating " + Context.WIFI_SCANNING_SERVICE);
        mHandlerThread = new HandlerThread("WifiScanningService");
        mHandlerThread.start();
        mImpl = new WifiScanningServiceImpl(getContext(), mHandlerThread.getLooper(),
                WifiScannerImpl.DEFAULT_FACTORY,
                getContext().getSystemService(BatteryStatsManager.class),
                WifiInjector.getInstance());
    }

这里新创建了 HandlerThread 对象,调用其 start 开始运行,新建了 WifiScanningServiceImpl 对象 mImpl 实际完成对应的实现工作,而在 onStart 中将服务注册到 binder,在 onBootPhase 调用了 mImpl 的 startService 发送消息,在消息回调中创建了三个扫描状态机对象并启动三个扫描对象,同时创建 ClientHandler 对象处理消息。

4. ConnectivityService 初始化

            t.traceBegin("StartConnectivityService");
            // This has to be called after NetworkManagementService, NetworkStatsService
            // and NetworkPolicyManager because ConnectivityService needs to take these
            // services to initialize.
            // TODO: Dynamically load service-connectivity.jar by using startServiceFromJar.
            mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_CLASS);
            connectivity = IConnectivityManager.Stub.asInterface(
                    ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
            // TODO: Use ConnectivityManager instead of ConnectivityService.
            networkPolicy.bindConnectivityManager(connectivity);
            t.traceEnd();

这里使用的是 ConnectivityServiceInitializer 类,在其构造函数中仅仅是创建了 ConnectivityService 类的对象,以 NETWORKMANAGEMENT_SERVICE,NETWORK_STATS_SERVICE 和 NETWORK_POLICY_SERVICE服务的引用为参数进行了初始化,而其 onStart 接口也是将服务注册到 binder 中,没有更多操作。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值