Android WiFi框架
下面是根据Android15,简单记录Android WiFi 框架流程
SystemServer启动WiFi服务
一.WiFi Service启动业务流程
SystemServer是虚拟机第一个创建的进程,主要用于启动Framework层的服务,WiFi Service业务流程代码在以下路径。
frameworks/base/services/java/com/android/server/SystemServer.java
SystemServer进程里面有个main()方法,main 方法如下:
public final class SystemServer implements Dumpable {
...
public static void main(String[] args) {
new SystemServer().run();
}
...
}
然后再run()方法中,启动各种系统服务,其中在startOtherServices启动WiFi服务。
public final class SystemServer implements Dumpable {
...
private void run() {
...
// Start services.
try {
t.traceBegin("StartServices");
startBootstrapServices(t);//设备启动服务,电源管理和设备管理服务
startCoreServices(t);//核心服务i
startOtherServices(t);//其他服务,AMS,WiFi,蓝牙
startApexServices(t);
// Only update the timeout after starting all the services so that we use
// the default timeout to start system server.
updateWatchdogTimeout(t);
CriticalEventLog.getInstance().logSystemServerStarted();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
...
}
}
下面我们查看startOtherServices()方法,startOtherServices方法依次启动了WIFI服务、WIFI扫描服务、RTT服务、Aware新型无线通信技术服务、P2P服务。
public final class SystemServer implements Dumpable {
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 static final String CONNECTIVITY_SERVICE_APEX_PATH =
"/apex/com.android.tethering/javalib/service-connectivity.jar";
private static final String CONNECTIVITY_SERVICE_INITIALIZER_CLASS =
"com.android.server.ConnectivityServiceInitializer";
private static final String NETWORK_STATS_SERVICE_INITIALIZER_CLASS =
"com.android.server.NetworkStatsServiceInitializer";
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI)) {
// Wifi Service must be started first for wifi-related services.
if (!isArc) {
t.traceBegin("StartWifi");
//开启WiFi服务
mSystemServiceManager.startServiceFromJar(
WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
//开启扫描WiFi
t.traceBegin("StartWifiScanning");
mSystemServiceManager.startServiceFromJar(
WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
}
// ARC - ArcNetworkService registers the ARC network stack and replaces the
// stock WiFi service in both ARC++ container and ARCVM. Always starts the ARC network
// stack regardless of whether FEATURE_WIFI is enabled/disabled (b/254755875).
if (isArc) {
t.traceBegin("StartArcNetworking");
mSystemServiceManager.startService(ARC_NETWORK_SERVICE_CLASS);
t.traceEnd();
}
//开启WiFi 服务RTT
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_RTT)) {
t.traceBegin("StartRttService");
mSystemServiceManager.startServiceFromJar(
WIFI_RTT_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
开启WiFi AWARE服务
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_AWARE)) {
t.traceBegin("StartWifiAware");
mSystemServiceManager.startServiceFromJar(
WIFI_AWARE_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
//开启WiFi P2P服务
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_DIRECT)) {
t.traceBegin("StartWifiP2P");
mSystemServiceManager.startServiceFromJar(
WIFI_P2P_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
...
}
...
}
二、服务定义
根据上面源码分析中开启的服务,可以结合网上资料,得到以下WiFi定义
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的发现、设备连接和数据传输等过程,并提供相应的回调接口,以便应用程序可以响应相关事件和处理逻辑。
三. WiFi service启动流程
上面源码分析我们分析了SystemService启动WiFi几个WiFiService业务流程,下面我们分析单个WiFiService()启动过程。
具体代码分析如下
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public final class SystemServiceManager implements Dumpable {
/**
* Starts a service by class name and standalone jar path where the service lives.
*
* In general, this should only be used for services in {@code STANDALONE_SYSTEMSERVER_JARS},
* which in turn derives from {@code PRODUCT_STANDALONE_SYSTEM_SERVER_JARS} and
* {@code PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS}.
*
* @return The service instance.
*/
public SystemService startServiceFromJar(String className, String path) {
//获取对象加载器
PathClassLoader pathClassLoader =
SystemServerClassLoaderFactory.getOrCreateClassLoader(
path, this.getClass().getClassLoader(), isJarInTestApex(path));
final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader);
return startService(serviceClass);
}
...
/*
* Loads and initializes a class from the given classLoader. Returns the class.
*/
@SuppressWarnings("unchecked")
@android.ravenwood.annotation.RavenwoodKeep
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);
}
}
...
}
系统主要是通过调用SystemServiceManager的startServiceFromJar方法来启动WifiService的。
startServiceFromJar方法先是获取类加载器,然后调用loadClassFromLoader方法结合类名和类加载器,获取类路径,最后调用startService方法启动WifiService服务。
2.SystemServiceManager的startService方法如下所示
public final class SystemServiceManager implements Dumpable {
private List<SystemService> mServices;
...
/**
* 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.
*/
/**
* 创建一个系统服务,该服务必须是com.android.server.SystemService的子类
*
* @param serviceClass 一个实现了SystemService接口的Java类
* @return 返回一个服务实例对象
*/
@android.ravenwood.annotation.RavenwoodKeep
@UsesReflection(
@KeepTarget(
instanceOfClassConstantExclusive = SystemService.class,
methodName = "<init>",
methodParameterTypePatterns = {@TypePattern(constant = Context.class)}))
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);
}
}
@android.ravenwood.annotation.RavenwoodKeep
public void startService(@NonNull final SystemService service) {
// Check if already started
String className = service.getClass().getName();
if (mServiceClassnames.contains(className)) {
Slog.i(TAG, "Not starting an already started service " + className);
return;
}
mServiceClassnames.add(className);
// 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");
}
...
}
3、继续来看下WifiService的构造方法和onStart方法。
public final class WifiService extends SystemService {
private static final String TAG = "WifiService";
// Notification channels used by the wifi service.
public static final String NOTIFICATION_NETWORK_STATUS = "NETWORK_STATUS";
public static final String NOTIFICATION_NETWORK_ALERTS = "NETWORK_ALERTS";
public static final String NOTIFICATION_NETWORK_AVAILABLE = "NETWORK_AVAILABLE";
public static final String NOTIFICATION_APM_ALERTS = "APM_ALERTS";
private final WifiServiceImpl mImpl;
private final WifiContext mWifiContext;
public WifiService(Context contextBase) {
super(contextBase);
mWifiContext = new WifiContext(contextBase);
WifiInjector injector = new WifiInjector(mWifiContext);
mImpl = new WifiServiceImpl(mWifiContext, injector);
}
@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();//检查是否需要启动wifi
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mImpl.handleBootCompleted();
}
}
}
从应用层看WiFi流程
WifiSettings --> WifiManager
点击 wifi button 开启wifi 触发的代码流程如下,
1.wifiSettings 响应onPreferenceTreeClick 送往WifiEnable
2.WifiEnabler 根据传入的状态,call WifiManager 设置wifi状态 (开启跳转到WifiServiceImpl)
packages/apps/Settings/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
@Override
public boolean onPreferenceTreeClick(Preference preference) {
...
return super.onPreferenceTreeClick(preference);
}
packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
@Override
public boolean onSwitchToggled(boolean isChecked) {
...
if (!mWifiManager.setWifiEnabled(isChecked)) {
...
}
2. WifiManager --> WifiService --> WifiServiceImpl -->WifiController
逐级进入WifiService,WifiServiceImpl ,WifiController,WifiStateMachinePrime,WifiNative 等完成CMD_WIFI_TOGGLED的火炬传递
注意随着Android 版本升级后,接递火炬CMD_WIFI_TOGGLED的顺序也发生了变化
Android P 版本WifiServiceImpl 将CMD_WIFI_TOGGLED 先送到了WifiController处理,这里稍微有点儿复杂的状态机(都会涉及到处理此cmd),具体根据设备所处状态来跟就可以。(这里以设备从开机状态第一次打开wifi为场景进行说明,此case 直接会进入)
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
public boolean setWifiEnabled(boolean enabled){
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); // jump to WifiServiceImpl
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
public synchronized boolean setWifiEnabled(String packageName, boolean enable){
....
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
}
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java
class StaDisabledState extends State {
....
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
.....
transitionTo(mDeviceActiveState); // jump to DeviceActiveState
}
}
class DeviceActiveState extends State {
public void enter() {
mWifiStateMachinePrime.enterClientMode(); // jump to WifiStateMachinePrime
mWifiStateMachine.setHighPerfModeEnabled(false);
}
}
packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java
@Deprecated
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
正常WiFi启动流程
1. WiFiManger
WiFiManger是暴露给api的类
位置:packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java
@SystemService(Context.WIFI_SERVICE)
public class WifiManager {
public boolean setWifiEnabled(boolean enabled) {
try {
// (1)调用 Service 的 setWifiEnabled 方法
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
2.WiFiServiceImpl
WiFiServiceImpl 是Manager接口具体实现类
位置:packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
public class WifiServiceImpl extends BaseWifiService {
private static final String TAG = "WifiService";
// (1) setWifiEnabled 方法
public synchronized boolean setWifiEnabled(String packageName, boolean enable) {
// If Airplane mode is enabled, only privileged apps are allowed to toggle Wifi
if (mSettingsStore.isAirplaneModeOn() && !isPrivileged) {
mLog.err("setWifiEnabled in Airplane mode: only Settings can toggle wifi").flush(); //异常日志
return false;
}
...
// (2) 继续追踪setWifiEnabledInternal 方法
setWifiEnabledInternal(packageName, enable, callingUid, callingPid, isPrivileged);
return true;
}
// (3) 查看 setWifiEnabledInternal 方法实现
private void setWifiEnabledInternal(String packageName, boolean enable,
int callingUid, int callingPid, boolean isPrivileged) {
// (4) 这里有打印哦,打印哪个应用打开还是关闭wifi 的日志
mLog.info("setWifiEnabled package=% uid=% enable=% isPrivileged=%").c(packageName)
.c(callingUid).c(enable).c(isPrivileged).flush(); //wifi 打开日志
。。。
// (5) 继续追踪 ActiveModeWarden.wifiToggled
mActiveModeWarden.wifiToggled(new WorkSource(callingUid, packageName));
mLastCallerInfoManager.put(WifiManager.API_WIFI_ENABLED, Process.myTid(),
callingUid, callingPid, packageName, enable); //一些属性的保存,可以不用管
}
}
3.ActiveModeWarden.java
位置:packages/modules/Wifi/service/java/com/android/server/wifi/ActiveModeWarden.java
public class ActiveModeWarden {
private static final String TAG = "WifiActiveModeWarden";
//(1) wifi打开消息发送方法
public void wifiToggled(WorkSource requestorWs) {
mWifiController.sendMessage(WifiController.CMD_WIFI_TOGGLED, requestorWs);
}
//(2) wifi打开消息的接收
//内部类,wifi执行打开是Disable 的状态
class DisabledState extends BaseState {
@Override
public void enter() {
log("DisabledState.enter()");
super.enter();
if (hasAnyModeManager()) {
Log.e(TAG, "Entered DisabledState, but has active mode managers");
}
}
@Override
public boolean processMessageFiltered(Message msg) {
switch (msg.what) {
//(3) wifi打开消息处理
case CMD_WIFI_TOGGLED:
case CMD_SCAN_ALWAYS_MODE_CHANGED:
handleStaToggleChangeInDisabledState((WorkSource) msg.obj);
break;
}
default:
return NOT_HANDLED;
}
return HANDLED;
}
//(4) 内部类的处理方法 handleStaToggleChangeInDisabledState
private void handleStaToggleChangeInDisabledState(WorkSource requestorWs) {
if (shouldEnableSta()) {
startPrimaryOrScanOnlyClientModeManager(requestorWs);
transitionTo(mEnabledState);
}
}
}
//(4) 具体的处理方法 startPrimaryOrScanOnlyClientModeManager
private boolean startPrimaryOrScanOnlyClientModeManager(WorkSource requestorWs) {
//(5)这里其实是判断了wifi_on那个Settings属性
ActiveModeManager.ClientRole role = getRoleForPrimaryOrScanOnlyClientModeManager();
if (role == ROLE_CLIENT_PRIMARY) { //(6)wifi 打开是进这里
return startPrimaryClientModeManager(requestorWs);
} else if (role == ROLE_CLIENT_SCAN_ONLY) {
return startScanOnlyClientModeManager(requestorWs);
} else {
return false;
}
}
// (7)继续追踪方法
private boolean startPrimaryClientModeManager(WorkSource requestorWs) {
Log.d(TAG, "Starting primary ClientModeManager in connect mode");
//(8)这里创建了 ConcreteClientModeManager 对象,看起来没做啥,其实创建对象会做事情
ConcreteClientModeManager manager = mWifiInjector.makeClientModeManager(
new ClientListener(), requestorWs, ROLE_CLIENT_PRIMARY, mVerboseLoggingEnabled);
mClientModeManagers.add(manager); //连接对象被接入队列管理,可以不用关注,断开会被移除
mLastPrimaryClientModeManagerRequestorWs = requestorWs;
return true;
}
}
4、ConcreteClientModeManager
ConcreteClientModeManager 相关一个系统层的wifi Manager,系统内部使用;
位置:packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
public class ConcreteClientModeManager implements ClientModeManager {
private static final String TAG = "WifiClientModeManager";
//(1) ConcreteClientModeManager 构造方法
ConcreteClientModeManager(Context context,...) {
mContext = context;
mWifiNative = wifiNative;
...
//(2)构造方法中,发送wifi开启
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START, mTargetRoleChangeInfo);
}
//(3)内部状态类,接收消息
//内部类,未开启wifi前是IdleState状态
private class IdleState extends State {
@Override
public void enter() {
Log.d(getTag(), "entering IdleState");
mClientInterfaceName = null;
mIfaceIsUp = false;
}
@Override
public boolean processMessage(Message message) {
switch (message.what) {
//(3)接收消息
case CMD_START:
// Always start in scan mode first.
RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
// (4) native 方法调用,拉起节点,一般是wlan0
mClientInterfaceName = mWifiNative.setupInterfaceForClientInScanMode(
mWifiNativeInterfaceCallback, roleChangeInfo.requestorWs);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(getTag(), "Failed to create ClientInterface. Sit in Idle");
takeBugReportInterfaceFailureIfNeeded(
"Wi-Fi scan STA interface HAL failure");
mModeListener.onStartFailure(ConcreteClientModeManager.this);
break;
}
if (roleChangeInfo.role instanceof ClientConnectivityRole) { //默认是进入这里
sendMessage(CMD_SWITCH_TO_CONNECT_MODE, roleChangeInfo);
transitionTo(mStartedState);
} else {
mScanRoleChangeInfoToSetOnTransition = roleChangeInfo;
transitionTo(mScanOnlyModeState);
}
break;
default:
Log.d(getTag(), "received an invalid message: " + message);
return NOT_HANDLED;
}
return HANDLED;
}
}
}
5.WifiNative
public class WifiNative {
private static final String TAG = "WifiNative";
private final WifiVendorHal mWifiVendorHal;
private final IfaceManager mIfaceMgr = new IfaceManager(); //内部类,调用的Iface
public String setupInterfaceForClientInScanMode(
@NonNull InterfaceCallback interfaceCallback, @NonNull WorkSource requestorWs) {
synchronized (mLock) {
if (!startHal()) { //(1) 初始化驱动和vendor hal
Log.e(TAG, "Failed to start Hal");
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
return null;
}
// (2) 初始化interface
Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_SCAN);
if (iface == null) {
Log.e(TAG, "Failed to allocate new STA iface");
return null;
}
iface.externalListener = interfaceCallback;
iface.name = createStaIface(iface, requestorWs);
if (TextUtils.isEmpty(iface.name)) {
Log.e(TAG, "Failed to create iface in vendor HAL");
mIfaceMgr.removeIface(iface.id);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
return null;
}
// (3)初始化wificond
if (!mWifiCondManager.setupInterfaceForClientMode(iface.name, Runnable::run,
new NormalScanEventCallback(iface.name),
new PnoScanEventCallback(iface.name))) {
Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
teardownInterface(iface.name);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
return null;
}
iface.networkObserver = new NetworkObserverInternal(iface.id);
//(4)监听interface的down/up
if (!registerNetworkObserver(iface.networkObserver)) {
Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
teardownInterface(iface.name);
return null;
}
//(5)启动supplicant监听(但是此时supplicant进程还未启动)
mWifiMonitor.startMonitoring(iface.name);
// Just to avoid any race conditions with interface state change callbacks,
// update the interface state before we exit.
onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
mWifiVendorHal.enableLinkLayerStats(iface.name);
Log.i(TAG, "Successfully setup " + iface); //成功启动wifi节点
//(6)获取芯片支持的wifi feature
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
return iface.name;
}
}
//(7) 继续分析:初始化驱动
private boolean startHal() {
synchronized (mLock) {
if (!mIfaceMgr.hasAnyIface()) { //(8) 判断节点是否存在
if (mWifiVendorHal.isVendorHalSupported()) { //(9) 判断底层是否支持
if (!mWifiVendorHal.startVendorHal()) { //(10) **重点:判断是否可以正常启动节点
Log.e(TAG, "Failed to start vendor HAL");
return false;
}
if (SdkLevel.isAtLeastS()) {
mWifiVendorHal.setCoexUnsafeChannels(mCachedCoexUnsafeChannels, mCachedCoexRestrictions);
}
} else {
Log.i(TAG, "Vendor Hal not supported, ignoring start.");
}
}
registerWificondListenerIfNecessary();
return true;
}
}
}
6.WifiVendorHal
位置:packages/modules/Wifi/service/java/com/android/server/wifi/WifiVendorHal.java
/**
* Vendor HAL via HIDL
*/
public class WifiVendorHal {
private final HalDeviceManager mHalDeviceManager;
// (1)追踪 startVendorHal
public boolean startVendorHal() {
synchronized (sLock) {
//(2) 关键 mHalDeviceManager.start
if (!mHalDeviceManager.start()) {
mLog.err("Failed to start vendor HAL").flush();
return false;
}
mLog.info("Vendor Hal started successfully").flush();
return true;
}
}
}
HalDeviceManager
import android.hardware.wifi.V1_0.IWifi;
/**
* Handles device management through the HAL (HIDL) interface.
*/
public class HalDeviceManager {
private static final String TAG = "HalDevMgr";
private IWifi mWifi;
//(1) 继续追踪 HalDeviceManager.start
public boolean start() {
return startWifi();
}
//(2) startWifi 实现
private boolean startWifi() {
if (VDBG) Log.d(TAG, "startWifi");
initIWifiIfNecessary();
synchronized (mLock) {
try {
if (mWifi == null) {
Log.w(TAG, "startWifi called but mWifi is null!?");
return false;
} else {
int triedCount = 0;
while (triedCount <= START_HAL_RETRY_TIMES) { //最多启动start三次
WifiStatus status = mWifi.start();
if (status.code == WifiStatusCode.SUCCESS) {
initIWifiChipDebugListeners();
managerStatusListenerDispatch();
if (triedCount != 0) { //(3)启动慢,一次没有启动成功的情况,这里才会有日志!
Log.d(TAG, "start IWifi succeeded after trying " + triedCount + " times");
}
WifiChipInfo[] wifiChipInfos = getAllChipInfo();
if (wifiChipInfos != null) {
mCachedStaticChipInfos =
convertWifiChipInfoToStaticChipInfos(getAllChipInfo());
saveStaticChipInfoToStore(mCachedStaticChipInfos);
} else {
Log.e(TAG, "Started wifi but could not get current chip info.");
}
return true;
} else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
// Should retry. Hal might still be stopping. the registered event
// callback will not be cleared.
Log.e(TAG, "Cannot start IWifi: " + statusString(status)
+ ", Retrying...");
try {
Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
} catch (InterruptedException ignore) {
// no-op
}
triedCount++;
} else {
// Should not retry on other failures.
// Will be handled in the onFailure event.
Log.e(TAG, "Cannot start IWifi: " + statusString(status));
return false;
}
}
Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
return false;
}
} catch (RemoteException e) {
Log.e(TAG, "startWifi exception: " + e);
return false;
}
}
}
}
总结上述流程大概为:
WiFiManager->WifiServiceLmpl->ActiveModeWarden->ConcreteClientModeManager->WifiNative->WifiVendorHal->HalDeviceManager->wifi.cpp
WifiManager.setWifiEnabled()->
WifiServiceImpl.setWifiEnabled()->setWifiEnabledInternal()->
ActiveModeWarden.wifiToggled().DisabledState.processMessageFiltered()->handleStaToggleChangeInDisabledState()->startPrimaryOrScanOnlyClientModeManager()->
ConcreteClientModeManager->startPrimaryClientModeManager()->
ConcreteClientModeManager.ConcreteClientModeManager()->sendMessage()->processMessage()
WifiNative->setupInterfaceForClientInScanMode->startHal->startVendorHal()
WifiVendorHal.startVendorHal()->!mHalDeviceManager.start()
HalDeviceManager.start()->startWifi()
8.wifi.cpp
Hal 层代码
位置:hardware/interfaces/wifi/aidl/default/wifi.cpp
Return<void> Wifi::start(start_cb hidl_status_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal,
hidl_status_cb);
}
WifiStatus Wifi::startInternal() {
if (run_state_ == RunState::STARTED) {
return createWifiStatus(WifiStatusCode::SUCCESS);
} else if (run_state_ == RunState::STOPPING) {
return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
}
WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
if (wifi_status.code == WifiStatusCode::SUCCESS) {
// Register the callback for subsystem restart
const auto& on_subsystem_restart_callback = [this](const std::string& error) {
WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
LOG(INFO) << "Attempting to invoke onSubsystemRestart "
"callback";
if (!callback->onSubsystemRestart(wifi_status).isOk()) {
LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
} else {
LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
"callback";
}
}
};
// Create the chip instance once the HAL is started.
android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId;
for (auto& hal : legacy_hals_) {
chips_.push_back(
new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
feature_flags_, on_subsystem_restart_callback));
chipId++;
}
run_state_ = RunState::STARTED;
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onStart().isOk()) {
LOG(ERROR) << "Failed to invoke onStart callback";
};
}
LOG(INFO) << "Wifi HAL started";
} else {
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onFailure(wifi_status).isOk()) {
LOG(ERROR) << "Failed to invoke onFailure callback";
}
}
LOG(ERROR) << "Wifi HAL start failed";
// Clear the event callback objects since the HAL start failed.
event_cb_handler_.invalidate();
}
return wifi_status;
}
WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
// ... ...
mode_controller_->initialize(); // 加载驱动 driver_tool_->LoadDriver()
legacy_hals_ = legacy_hal_factory_->getHals();
for (auto& hal : legacy_hals_) {
legacy_hal::wifi_error legacy_status = hal->initialize();
// ... ...
}
// ... ...
}
std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() {
if (legacy_hals_.empty()) {
// 先从已链接的so库中初始化vendor hal的接口(函数指针赋值)
// 如果失败,证明是多wifi芯片的设备,需要从descriptor.xml初始化
if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
for (auto& desc : descs_) {
std::shared_ptr<WifiLegacyHal> hal =
std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary);
legacy_hals_.push_back(hal);
}
}
return legacy_hals_;
}
wifi.cpp 主要工作:
通过wifi_mode_controller加载驱动
初始化所有的HAL接口(legacy_hal_factory_->getHals())
initVendorHalDescriptorFromLinked
initVendorHalsDescriptorList
wifi_mode_controller
位置:hardware/interfaces/wifi/aidl/default/wifi_mode_controller.cpp
bool WifiModeController::initialize() {
if (!driver_tool_->LoadDriver()) {
LOG(ERROR) << "Failed to load WiFi driver";
return false;
}
return true;
}
driver_tool
位置frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp
bool DriverTool::LoadDriver() {
return ::wifi_load_driver() == 0;
}
wifi_load_driver
位置:frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp
int wifi_load_driver() {
#ifdef WIFI_DRIVER_MODULE_PATH
#ifdef DRIVER_PRELOAD_SUPPORT
hook_for_wifi_load_driver();
#endif
if (is_wifi_driver_loaded()) {
return 0;
}
if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1;
#endif
#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
if (is_wifi_driver_loaded()) {
return 0;
}
if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) {
#ifdef WIFI_DRIVER_MODULE_PATH
PLOG(WARNING) << "Driver unloading, err='fail to change driver state'";
if (rmmod(DRIVER_MODULE_NAME) == 0) {
PLOG(DEBUG) << "Driver unloaded";
} else {
// Set driver prop to "ok", expect HL to restart Wi-Fi.
PLOG(DEBUG) << "Driver unload failed! set driver prop to 'ok'.";
property_set(DRIVER_PROP_NAME, "ok");
}
#endif
return -1;
}
#endif
is_driver_loaded = true;
return 0;
}
wifi_hal_hook
frameworks/opt/net/wifi/libwifi_hal/wifi_hal_hook.h
#ifndef WIFI_DRIVER_MODULE_PATH
#define WIFI_DRIVER_MODULE_PATH "/vendor/lib/modules/"
#define DRIVER_MODULE_NAME get_wifi_driver_module_name()
#define DRIVER_MODULE_TAG hal_get_driver_module_tag()
#define DRIVER_MODULE_PATH hal_get_driver_module_path()//读取模块路径
#define DRIVER_MODULE_ARG hal_get_driver_module_arg()
Android15 Wifi启动 完整流程:
(1) WifiManager.java
(2) WifiServiceImpl.java
(3) ActivityModenWarden.java
(4) ConcreteClientModeManager.java
(5) WifiNative.java
(6) WIfiVendorHar.java
(7) HalDeviceManager.java
(8) wifi.cpp //HAl层
(9) HAl 往下
Android 15 wifi流程图
位置 | 文件 | 内部类 | 方法 | 其他 |
---|---|---|---|---|
app | WiFiEnabler | onSwitchToggled | ||
modles/wifi | WifiManager.java | setWifiEnabled | ||
modles/wifi | WifiServiceImpl.java | setWifiEnabled | ||
modles/wifi | ActiveModeWarden.java | setWifiEnabled | ||
modles/wifi | ActiveModeWarden.java | WifiController | sendMessage | WifiController.CMD_WIFI_TOGGLED |
modles/wifi | ActiveModeWarden.java | WifiController | processMessageFiltered | WifiController.CMD_WIFI_TOGGLED |
modles/wifi | ActiveModeWarden.java | WifiController | handleStaToggleChangeInDisabledState | |
modles/wifi | ActiveModeWarden.java | startPrimaryOrScanOnlyClientModeManager | ||
modles/wifi | ActiveModeWarden.java | startPrimaryClientModeManager | ||
modles/wifi | ConcreteClientModeManager.java | sendMessage | ||
modles/wifi | ActiveModeWarden.java | IdleState | processMessage | CMD_WIFI_TOGGLED |
modles/wifi | WifiNative.java | startHal | ||
modles/wifi | WifiNative.java | startVendorHal | ||
modles/wifi | WifiVendorHal.java | startVendorHal | ||
modles/wifi | HalDeviceManager.java | start() | ||
modles/wifi | HalDeviceManager.java | startWifi() | ||
HAL | wifi.cpp | start() | ||
HAL | wifi.cpp | startInternal() | ||
HAL | wifi.cpp | initializeModeControllerAndLegacyHal() | ||
HAL | wifi_mode_controller.cpp | initialize() | ||
frameworks | driver_tool.cpp | LoadDriver() | ||
frameworks | wifi_hal_common.cpp | wifi_load_driver() | ||
frameworks | wifi_hal_common.cpp | hook_for_wifi_load_driver() |