Android 6.0 WifiService的启动

版权声明:本文为博主原创文章,未经博主允许不得转载。https://blog.csdn.net/huangweiqing80/article/details/82702820
wifi框架中有两个非常重要的状态机:WifiController和WifiStateMachine,它们一起管理着wifi的各个状态以及状态之间的切换。WifiMonitor负责从wpa_supplicant接收事件,并且和WifiStateMachine交互。它们最终都会调用wifiNative,最终和wpa_supplicant交互。

一.WifiService的启动
WifiService的启动可用如下简单时序图表示:
这里写图片描述
启动过程的图示画的比较简单,下面就顺着这个思路理一下代码的实现。
1.1 启动WifiService
1.1.1 在SystemServer.java的 startOtherServices() 方法中,启动了WifiService,代码如下
frameworks/base/services/java/com/android/server/SystemServer.java

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

                mSystemServiceManager.startService("com.android.server.wifi.RttService");

其中用到的WIFI_P2P_SERVICE_CLASS,WIFI_SERVICE_CLASS两个变量的值如下:

    private static final String WIFI_SERVICE_CLASS =
            "com.android.server.wifi.WifiService";
    private static final String WIFI_P2P_SERVICE_CLASS =
            "com.android.server.wifi.p2p.WifiP2pService";

以上代码可以看到,SystemServier中启动的Wifi相关的服务有四个,从上往下依次是WifiP2pService,WifiService,wifi扫描附近热点的服务WifiScanningService以及以太网服务RttService。
1.1.2.
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
下面我们看下WifiService的启动过程。
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

    /**
     * Starts a service by class name.
     *
     * @return The service instance.
     */
    @SuppressWarnings("unchecked")
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Slog.i(TAG, "Starting " + className);
            throw new RuntimeException("Failed to create service " + className
                    + ": service class not found, usually indicates that the caller should "
                    + "have called PackageManager.hasSystemFeature() to check whether the "
                    + "feature is available on this device before trying to start the "
                    + "services that implement it", ex);
        }
        return startService(serviceClass);
    }

startService方法中通过Class.forName获得一个Class实例serviceClass,但是这还不是WifiService的实例,然后调用startService(serviceClass)进一步处理。这两个startService方法是重载方法,他们的参数类型不同。

    /**
     * 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.
     */
    @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        final String name = serviceClass.getName();
        Slog.i(TAG, "Starting " + 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 {
            // 获取service类中包含一个Context参数的构造函数
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            // 创建service对象
            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);
        }

        // Register it.
        mServices.add(service);

        // Start it.
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + name
                    + ": onStart threw an exception", ex);
        }
        return service;
    }

在这个startService方法中,使用 Constructor constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);构造了一个WifiService的实例,然后使用mServices.add(service);向系统注册WifiService,并调用WifiService的onStart方法。
1.2. 实例化WifiServiceImpl
WifiService的构造方法如下:
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiService.java

public final class WifiService extends SystemService {

    private static final String TAG = "WifiService";
    final WifiServiceImpl mImpl;

    public WifiService(Context context) {
        super(context);
        mImpl = new WifiServiceImpl(context);
    }

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

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            mImpl.checkAndStartWifi();
        }
    }
}

wifiService构造函数中新建了一个WifiServiceImpl实例,它才是Wifi管理服务真正的实现者,在1.2中构造函数调用后不是调用了WifiService的onStart方法吗?在onStart方法中发布了Wifi服务,发布的WifiServiceImpl的实例。发布的过程如下:

    /**
     * Publish the service so it is accessible to other services and apps.
     */
    protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }

    /**
     * Publish the service so it is accessible to other services and apps.
     */
    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        ServiceManager.addService(name, service, allowIsolated);
    }

也就是说还是调用了ServiceManager的addService方法来发布服务。
通过以上分析,我们知道了真的WifiService是WifiServiceImpl
1.3WifiServiceImpl的构造方法
WifiServiceImpl的构造方法如下:
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

    public WifiServiceImpl(Context context) {
        mContext = context;

        mInterfaceName =  SystemProperties.get("wifi.interface", "wlan0");

        mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);
        mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName, mTrafficPoller);
        mWifiStateMachine.enableRssiPolling(true);
        mBatteryStats = BatteryStatsService.getService();
        mPowerManager = context.getSystemService(PowerManager.class);
        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
        mUserManager = UserManager.get(mContext);

        mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
        mSettingsStore = new WifiSettingsStore(mContext);

        HandlerThread wifiThread = new HandlerThread("WifiService");
        wifiThread.start();
        mClientHandler = new ClientHandler(wifiThread.getLooper());
        mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
        mWifiController = new WifiController(mContext, this, wifiThread.getLooper());
    }

这里面做的事情还是很多的,主要有以下几点:
1.mInterfaceName 从系统属性中获得mInterfaceName,它的值一般就是wlan0; getProperty(String key, String def) 获取用指定键描述的系统属性(从系统环境或*.properties等配置文件中读取key对应的值,当key值为NULL时,返回def的值; 当key值不为NULL时,返回key的值 )。
2.实例化mTrafficPoller,这个实例的作用从其类的简介(Polls for traffic stats and notifies the clients )上可以看出他是用来查询流量统计信息比通知给客户端的。
3.实例化mWifiStateMachine ,这个实例代表着一个Wifi状态机,它定义了wifi的很多状态,通过消息驱动状态的转变。
4.获得mBatteryStats ,mPowerManager 对象,用于wifi的电源管理,
5.实例化mNotificationController, 处理打开“打开wifi并且可以使用“的通知。
6.实例化wifiThread, 它是一个HandlerThread 的实例,HandlerThread 是一个内部有Looper的线程,wifiThread会一直监听消息,消息到来以后,通过mClientHandler 的handleMessage来处理消息。
7.实例化WifiStateMachineHandler, 用于发送和处理wifi状态机相关的消息。
8实例化.mWifiController, mWifiController是另一个状态机,它和mWifiStateMachine 不同,mWifiStateMachine 表述wifi具体的状态,比如supplicant启动/关闭状态,driver启动/关闭状态等,mWifiController 则更高一级的控制wifi设备的开关状态,wifi热点的开关状态等。 在状态机中的消息处理中完成驱动的加载或者启动supplicant等

猜你喜欢

转载自blog.csdn.net/huangweiqing80/article/details/82702820