WIFI作为种无线网络技术,是一种基于IEEE 802.11标准的局域网(LAN)技术。它使用无线电波进行通信,在家庭、办公室、公共场所等地方广泛应用。WIFI技术可以实现高速数据传输和便捷的网络连接,使设备可以通过无线方式在局域网内相互连接和通信。使用WIFI技术可以通过笔记本电脑、智能手机、平板电脑等设备接入互联网,同时也可以实现设备之间的直接通信和文件传输。WIFI技术通常工作在2.4GHz和5GHz两个频段,其中2.4GHz频段的信号覆盖范围更广,但传输速度较慢;而5GHz频段的信号覆盖范围较窄,但传输速度更快。
WIFI作为手机最常使用的功能之一,通过打开WIFI,扫描附近的热点网络,输入对应网络的连接密码,最终成功连接到互联网以享受网上冲浪,WIFI已经逐渐成为人们生活中必不可少的一部分。作为一名系统开发人员,对于WIFI各种行为的内部实现原理自然不可不知,本期我们将会先结合系统源码来具体分析一下和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服务。
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功能并进行无线网络连接。
RttService服务,用于支持RTT(Round Trip Time)功能。RTT是一种通过WIFI直接测量设备之间的往返时延的技术。
RTT可以在无需连接到互联网的情况下,通过WIFI直接测量两个设备之间的距离和相对位置。它利用WIFI芯片上的RTT功能,通过发送一系列特定的WIFI帧来测量往返时间,并根据信号的传播速度计算出设备之间的距离。
使用RTT功能,开发者可以实现更精确的位置服务、室内导航、室内定位等功能。例如,应用程序可以利用RTT功能提供更准确的室内导航,或者在游戏中使用设备之间的距离信息来提供更具交互性的体验。
RttService提供了访问RTT API的方法,使应用程序能够使用RTT功能来测量设备之间的往返时延和距离,并根据需要进行相应的业务逻辑处理。
WifiScanningService服务,用于执行WIFI扫描操作。它负责与设备的WIFI芯片通信,并进行扫描附近的可用WIFI网络,具体来说,WifiScanningService的主要职责包括:
执行WIFI扫描:WifiScanningService负责执行WIFI扫描操作,以获取附近可用的WIFI网络列表。它会发送扫描请求给设备的WIFI芯片,并接收并处理扫描结果。
管理扫描结果:WifiScanningService将扫描得到的WIFI网络信息进行整理和管理,包括网络的SSID(网络名称)、BSSID(网络唯一标识符)、信号强度、加密类型等。这些信息可以提供给应用程序使用。
提供扫描接口:WifiScanningService提供了一组接口供应用程序使用,以便请求WIFI扫描并获取扫描结果。应用程序可以根据需要发起扫描操作,并通过回调接收扫描结果。
总之,WifiScanningService是Android系统中负责执行WIFI扫描操作的服务。它与设备的WIFI芯片进行通信,执行扫描操作,并管理和提供扫描结果给应用程序使用。这样,应用程序可以获取附近可用的WIFI网络信息,并根据需求进行连接或其他操作。
WifiAwareService服务,用于支持WiFi Aware功能。WiFi Aware是一种新型的无线通信技术,它可以使设备在没有网络连接和基础设施的情况下直接进行通信。
通过使用WiFi Aware,设备可以发现并与附近的其他设备直接通信,而无需连接到现有的无线网络或蜂窝数据网络。这种直接通信方式可以提供更快的响应时间、更低的延迟和更高的传输速率,同时节省电量和减少网络拥塞。
WifiAwareService提供了访问WiFi Aware API的方法,使应用程序能够利用WiFi Aware功能实现直接通信。例如,应用程序可以使用WiFi Aware来查找并与其他设备共享文件、游戏、音乐等内容。
WifiP2pService服务,用于支持WIFI直连点对点(P2P)功能。WIFI P2P允许设备在没有传统无线网络基础设施的情况下直接进行通信。
通过使用WIFI P2P,设备可以以对等的方式互相发现,并建立直接的WIFI连接,而无需经过路由器或访问点。这种直连方式可以实现设备之间的快速文件传输、共享资源、多人游戏等功能,而无需连接到互联网。
WifiP2pService提供了访问WIFI P2P API的方法,使应用程序能够利用WIFI P2P功能实现直接设备之间的通信和数据传输。例如,应用程序可以使用WIFI P2P来传输文件、发送消息、共享多媒体内容等。
WifiP2pService负责管理WIFI P2P的发现、设备连接和数据传输等过程,并提供相应的回调接口,以便应用程序可以响应相关事件和处理逻辑。
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();
}
}
}