Android 12系统源码_WIFI(一)WIFI相关服务的启动流程

2024-01-03 14:54:07

前言

WIFI作为种无线网络技术,是一种基于IEEE 802.11标准的局域网(LAN)技术。它使用无线电波进行通信,在家庭、办公室、公共场所等地方广泛应用。WIFI技术可以实现高速数据传输和便捷的网络连接,使设备可以通过无线方式在局域网内相互连接和通信。使用WIFI技术可以通过笔记本电脑、智能手机、平板电脑等设备接入互联网,同时也可以实现设备之间的直接通信和文件传输。WIFI技术通常工作在2.4GHz和5GHz两个频段,其中2.4GHz频段的信号覆盖范围更广,但传输速度较慢;而5GHz频段的信号覆盖范围较窄,但传输速度更快。
WIFI作为手机最常使用的功能之一,通过打开WIFI,扫描附近的热点网络,输入对应网络的连接密码,最终成功连接到互联网以享受网上冲浪,WIFI已经逐渐成为人们生活中必不可少的一部分。作为一名系统开发人员,对于WIFI各种行为的内部实现原理自然不可不知,本期我们将会先结合系统源码来具体分析一下和WIFI相关的服务的启动流程。

一、SystemServer启动WIFI服务

1、系统启动后会启动JVM虚拟机,SystemServer 是虚拟机的第一个进程,由init进程fork 产生。主要用来启动frameworks层中的服务。SystemServer进程里面有个main()方法,main 方法如下:

frameworks/base/service/java/com/android/server/SystemServer.java

public final class SystemServer {
    public static void main(String[] args) {
        new SystemServer().run();
    }
}

2、main 方法里启动了 run() 方法,而在 run 方法中调用了startOtherServices() 方法:

public final class SystemServer {
   private void run() {
    	...代码省略...
        try {
            t.traceBegin("StartServices");
            startBootstrapServices(t);//引导服务
            startCoreServices(t);//核心服务
            startOtherServices(t);//其他服务
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }
    	...代码省略...
    }
}

3、系统主要是在startOtherServices方法中启动和WIFI相关服务的。

public final class SystemServer {

    private SystemServiceManager mSystemServiceManager;
    private static final String WIFI_APEX_SERVICE_JAR_PATH =
            "/apex/com.android.wifi/javalib/service-wifi.jar";
    private static final String WIFI_SERVICE_CLASS =
            "com.android.server.wifi.WifiService";
    private static final String WIFI_SCANNING_SERVICE_CLASS =
            "com.android.server.wifi.scanner.WifiScanningService";
    private static final String WIFI_RTT_SERVICE_CLASS =
            "com.android.server.wifi.rtt.RttService";
    private static final String WIFI_AWARE_SERVICE_CLASS =
            "com.android.server.wifi.aware.WifiAwareService";
    private static final String WIFI_P2P_SERVICE_CLASS =
            "com.android.server.wifi.p2p.WifiP2pService";

    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        ...代码省略...
            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI)) {
                // Wifi Service must be started first for wifi-related services.
                t.traceBegin("StartWifi");
                //WIFI服务
                mSystemServiceManager.startServiceFromJar(
                        WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                t.traceEnd();
                t.traceBegin("StartWifiScanning");
                //WIFI扫描服务
                mSystemServiceManager.startServiceFromJar(
                        WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                t.traceEnd();
            }

            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI_RTT)) {
                t.traceBegin("StartRttService");
                //RTT服务
                mSystemServiceManager.startServiceFromJar(
                        WIFI_RTT_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                t.traceEnd();
            }

            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI_AWARE)) {
                t.traceBegin("StartWifiAware");
                //Aware新型无线通信技术服务
                mSystemServiceManager.startServiceFromJar(
                        WIFI_AWARE_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                t.traceEnd();
            }

            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI_DIRECT)) {
                t.traceBegin("StartWifiP2P");
                //P2P服务
                mSystemServiceManager.startServiceFromJar(
                        WIFI_P2P_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                t.traceEnd();
            }

        ...代码省略...
    }
}

startOtherServices方法依次启动了WIFI服务、WIFI扫描服务、RTT服务、Aware新型无线通信技术服务、P2P服务。

二、服务定义

1 WifiService

WifiService是Android系统中的一个核心服务,负责管理和控制设备的WIFI功能。它是WIFI模块与Android系统其他组件之间的桥梁,提供了对WIFI的配置、连接、扫描等操作的接口,具体来说,WifiService的主要职责包括:

  • WIFI状态管理:WifiService监控WIFI的开启和关闭状态,并负责处理WIFI模块的启动和停止。它可以根据用户的操作或系统需求来控制WIFI的开关,并确保WIFI在正确的时机进行启动或关闭。

  • WIFI网络连接管理:WifiService负责处理WIFI网络的连接和断开操作。它可以扫描附近的WIFI网络,并提供接口供应用程序进行网络连接。同时,它还负责管理已连接的网络列表,自动连接已知的WIFI网络,并处理网络切换等操作。

  • 配置管理:WifiService管理WIFI的配置信息,包括保存和读取已存储的网络配置,提供接口供应用程序进行配置的增删改查操作。

  • WIFI扫描:WifiService负责执行WIFI的扫描操作,以获取附近可用的WIFI网络列表。它会定期执行扫描,并将扫描结果提供给应用程序使用。

  • WIFI P2P(点对点)功能:WifiService支持WIFI的点对点功能,允许设备直接建立WIFI连接进行通信和数据传输。

总之,WifiService是Android系统中负责管理和控制WIFI功能的关键服务,它提供了对WIFI的配置、连接和状态管理的接口,确保设备能够正常使用WIFI功能并进行无线网络连接。

2 RttService

RttService服务,用于支持RTT(Round Trip Time)功能。RTT是一种通过WIFI直接测量设备之间的往返时延的技术。

RTT可以在无需连接到互联网的情况下,通过WIFI直接测量两个设备之间的距离和相对位置。它利用WIFI芯片上的RTT功能,通过发送一系列特定的WIFI帧来测量往返时间,并根据信号的传播速度计算出设备之间的距离。

使用RTT功能,开发者可以实现更精确的位置服务、室内导航、室内定位等功能。例如,应用程序可以利用RTT功能提供更准确的室内导航,或者在游戏中使用设备之间的距离信息来提供更具交互性的体验。

RttService提供了访问RTT API的方法,使应用程序能够使用RTT功能来测量设备之间的往返时延和距离,并根据需要进行相应的业务逻辑处理。

3 WiFiScanningService

WifiScanningService服务,用于执行WIFI扫描操作。它负责与设备的WIFI芯片通信,并进行扫描附近的可用WIFI网络,具体来说,WifiScanningService的主要职责包括:

  • 执行WIFI扫描:WifiScanningService负责执行WIFI扫描操作,以获取附近可用的WIFI网络列表。它会发送扫描请求给设备的WIFI芯片,并接收并处理扫描结果。

  • 管理扫描结果:WifiScanningService将扫描得到的WIFI网络信息进行整理和管理,包括网络的SSID(网络名称)、BSSID(网络唯一标识符)、信号强度、加密类型等。这些信息可以提供给应用程序使用。

  • 提供扫描接口:WifiScanningService提供了一组接口供应用程序使用,以便请求WIFI扫描并获取扫描结果。应用程序可以根据需要发起扫描操作,并通过回调接收扫描结果。

总之,WifiScanningService是Android系统中负责执行WIFI扫描操作的服务。它与设备的WIFI芯片进行通信,执行扫描操作,并管理和提供扫描结果给应用程序使用。这样,应用程序可以获取附近可用的WIFI网络信息,并根据需求进行连接或其他操作。

4 WiFiAwareService

WifiAwareService服务,用于支持WiFi Aware功能。WiFi Aware是一种新型的无线通信技术,它可以使设备在没有网络连接和基础设施的情况下直接进行通信。

通过使用WiFi Aware,设备可以发现并与附近的其他设备直接通信,而无需连接到现有的无线网络或蜂窝数据网络。这种直接通信方式可以提供更快的响应时间、更低的延迟和更高的传输速率,同时节省电量和减少网络拥塞。

WifiAwareService提供了访问WiFi Aware API的方法,使应用程序能够利用WiFi Aware功能实现直接通信。例如,应用程序可以使用WiFi Aware来查找并与其他设备共享文件、游戏、音乐等内容。

5 WiFiP2pService

WifiP2pService服务,用于支持WIFI直连点对点(P2P)功能。WIFI P2P允许设备在没有传统无线网络基础设施的情况下直接进行通信。

通过使用WIFI P2P,设备可以以对等的方式互相发现,并建立直接的WIFI连接,而无需经过路由器或访问点。这种直连方式可以实现设备之间的快速文件传输、共享资源、多人游戏等功能,而无需连接到互联网。

WifiP2pService提供了访问WIFI P2P API的方法,使应用程序能够利用WIFI P2P功能实现直接设备之间的通信和数据传输。例如,应用程序可以使用WIFI P2P来传输文件、发送消息、共享多媒体内容等。

WifiP2pService负责管理WIFI P2P的发现、设备连接和数据传输等过程,并提供相应的回调接口,以便应用程序可以响应相关事件和处理逻辑。

三、WifiService的启动

1、上面我们简单介绍了和WIFI相关的几个服务,下面我们继续来分析WifiService启动的启动流程。

public final class SystemServer {

    private SystemServiceManager mSystemServiceManager;
    private static final String WIFI_APEX_SERVICE_JAR_PATH =
            "/apex/com.android.wifi/javalib/service-wifi.jar";
    private static final String WIFI_SERVICE_CLASS =
            "com.android.server.wifi.WifiService";

    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        ...代码省略...
            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_WIFI)) {
                // Wifi Service must be started first for wifi-related services.
                t.traceBegin("StartWifi");
                //WIFI服务
                mSystemServiceManager.startServiceFromJar(
                        WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                t.traceEnd();
            }
        ...代码省略...
    }
}

2、系统主要是通过调用SystemServiceManager的startServiceFromJar方法来启动WifiService的。

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public final class SystemServiceManager implements Dumpable {
    private final ArrayMap<String, PathClassLoader> mLoadedPaths = new ArrayMap<>();
    /**
     * 通过类名和Jar包路径启动服务
     */
    public SystemService startServiceFromJar(String className, String path) {
    	//获取路径类加载器
        PathClassLoader pathClassLoader = mLoadedPaths.get(path);
        if (pathClassLoader == null) {
        	//如果为空则创建对应的实例对象,并存储到集合中
            pathClassLoader = (PathClassLoader) ClassLoaderFactory.createClassLoader(
                    path, null /* librarySearchPath */, null /* libraryPermittedPath */,
                    this.getClass().getClassLoader(), Build.VERSION.SDK_INT,
                    true /* isNamespaceShared */, null /* classLoaderName */);
            mLoadedPaths.put(path, pathClassLoader);
        }
        final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader);
        return startService(serviceClass);
    }

    private static Class<SystemService> loadClassFromLoader(String className,
            ClassLoader classLoader) {
        try {
        	//结合类名和类加载器,获取类路径
            return (Class<SystemService>) Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("Failed to create service " + className
                    + " from class loader " + classLoader.toString() + ": 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. Also ensure that the correct path for the "
                    + "classloader is supplied, if applicable.", ex);
        }
    }

}

startServiceFromJar方法先是获取类加载器,然后调用loadClassFromLoader方法结合类名和类加载器,获取类路径,最后调用startService方法启动WifiService服务。

3、SystemServiceManager的startService方法如下所示。

public final class SystemServiceManager implements Dumpable {
    /**
     * 创建一个系统服务,该服务必须是com.android.server.SystemService的子类
     *
     * @param serviceClass 一个实现了SystemService接口的Java类
     * @return 返回一个服务实例对象
     */
    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 {
                //获取参数为Context的构造方法,通过反射创建service对象
                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方法
            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
    
    public void startService(@NonNull final SystemService service) {
        // Register it.
        //在类型为ArrayList<SystemService>的属性集合mServices中注册新创建的服务对象
        mServices.add(service);
        // Start it.
        //调用服务的onStart方法,开启服务
        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");
    }
 }

SystemServiceManager的startService首先会获取要启动的服务对象中带有Context参数的构造方法 ,并调用该构造方法创建服务实例对象,然后将WiFiService存放到类型为ArrayList的属性集合mServices中,并调用WiFiService的onStart方法。

4、继续来看下WifiService的构造方法和onStart方法。

public final class WifiService extends SystemService {

    private final WifiServiceImpl mImpl;
    private final WifiContext mWifiContext;

    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);
    }

    @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) {
            createNotificationChannels(mWifiContext);
            mImpl.checkAndStartWifi();
        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
            mImpl.handleBootCompleted();
        }
    }

}

文章来源:https://blog.csdn.net/abc6368765/article/details/135202543
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。