Android13 Wifi启动流程分析

04-11 680阅读

Android13 Wifi启动流程分析

文章目录

  • Android13 Wifi启动流程分析
    • 一、正常开关wifi 启动流程
      • 1、WifiManager
      • 2、WifiServiceImpl
      • 3、ActiveModeWarden
      • 4、ConcreteClientModeManager
      • 5、WifiNative
      • 6、WifiVendorHal
      • 7、HalDeviceManager
      • 8、wifi.cpp
      • 二、重启设备时自动开启wifi流程
        • 1、系统服务启动 SystemServer
        • 2、WifiService
        • 3、WifiServiceImpl
        • 4、ActiveModeWarden
        • 三、其他
          • 1、Android13 Wifi启动 完整流程:
          • 2、日志查看
            • 关键字和可以查看到的关键信息
            • 正常开启wifi日志:
            • 正常关闭wifi日志:
            • 缺少wifi硬件模组是开启wifi日志:
            • 3、wifi开关状态值
            • 4、之前写的一些wifi相关的知识

              本文对Android13 wifi 开启流程进行梳理,有需要的可以看看。

              如果遇到wifi 打不开问题,可以依照这个流程进行分析,看看具体是哪个流程出现问题。

              如果后续需要分析比Android13 更新的代码可以对比参考,毕竟Android11的代码变动比较大。

              本文最后有流程总结,代码分析过程还有最大一个亮点,每个类的流程分析都标志了数字,避免读着读着就迷路了。

              最后还有wifi开关相关日志过程分析。

              一、正常开关wifi 启动流程

              1、WifiManager

              WifiManager 是给应用暴露的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); //一些属性的保存,可以不用管
                  }
              	
              }
              

              WifiServiceImpl 的打印TAG 是 WifiService,wifi 开关有比较多相关日志,主要是看出开关日志和哪个应用调用的开关。

              3、ActiveModeWarden

              里面有一些关键日志,调试可以查看该日志。

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

              ActiveModeWarden 的日志 TAG 是 WifiActiveModeWarden,该文件的日志有打印目前wifi是从哪个状态进入进行操作的日志。

              往下走的 ConcreteClientModeManager 对象 比较特殊,你只要创建它,它就会默认执行开启wifi,往下看它的代码实现就可以看到,所以这里manager 未调用方法,只是加入到队列管理中,很多人可能会看懵,但是继续往下看它的构造方法就明白了。

              4、ConcreteClientModeManager

              ConcreteClientModeManager 相关一个系统层的wifi Manager,系统内部使用;

              Android11 中没有 ConcreteClientModeManager ,只有 ClientModeManager。

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

              ConcreteClientModeManager 的日志 TAG 是 WifiClientModeManager,

              该文件的日志有也是包含了一些状态下的操作信息。

              Android11 中 ClientModeManager 的日志 TAG 是 WifiClientModeManager。

              5、WifiNative

              WifiNative 是一个统筹调用底层接口的类,这个类往下的逻辑看起来好像没有太大修改。

              packages\modules\Wifi\service\java\com\android\server\wifi\WifiNative.java

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

              7、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  WifiVendorHal -> HalDeviceManager
              WifiNative.startHal() -> 
              WifiVendorHal.startVendorHal() ->
              HalDeviceManager.start() -> 
              HalDeviceManager.startWifi()
              

              HalDeviceManager 往下的 Hal 层代码是直接调用硬件接口的了。

              并且 IWifi 这些 接口类是系统编译生成的,没有具体的IWifi.java 文件,只有相关的class文件。

              8、wifi.cpp

              Hal 层代码

              hardware\interfaces\wifi\1.6\default\wifi.cpp

              Return 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) onSubsystemRestart(wifi_status).isOk()) {
                                  LOG(ERROR) initialize();
                      // ... ...
                  }
                  // ... ...
              }
              std::vector WifiLegacyHalFactory::getHals() {
                  if (legacy_hals_.empty()) {
                      // 先从已链接的so库中初始化vendor hal的接口(函数指针赋值)
                      // 如果失败,证明是多wifi芯片的设备,需要从descriptor.xml初始化
                      if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
                      for (auto& desc : descs_) {
                          std::shared_ptr hal =
                                  std::make_shared(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.cpp 已经是底层硬件实现了,这块代码其实我也不怎么了解,再往下不做具体分析了。

              这篇文章对底层逻辑讲得详细一下:

              https://blog.csdn.net/weixin_40588186/article/details/132837372

              二、重启设备时自动开启wifi流程

              系统启动时,其实就多了startServer的过程,并且在startOtherService中打开wifi。

              init.rc那些就不说了,直接从Java部分说起。

              1、系统服务启动 SystemServer

              SystemServer 是包含Java入口的类,并且启动了很多Android 关键服务。

              frameworks\base\services\java\com\android\server\SystemServer.java

              /**
               * Entry point to {@code system_server}.
               */
              public final class SystemServer implements Dumpable {
              private static final String WIFI_SERVICE_CLASS =        "com.android.server.wifi.WifiService";
                  /**
                   * The main entry point from zygote.
                   */
                   //(1)Java 端启动入口
                  public static void main(String[] args) {
                      new SystemServer().run();
                  }
              	//(2)启动系统服务
                  private void run() {
                      // Start services.
                      try {
                          t.traceBegin("StartServices");
                          startBootstrapServices(t);//设备启动服务,电源管理和设备管理服务
                          startCoreServices(t); //核心服务
                          startOtherServices(t);//(3)其他服务,AMS、WIFI、蓝牙那些
                          startApexServices(t);//启动app相关服务,这个是Android13 才有的。
                      } catch (Throwable ex) {
                          Slog.e("System", "******************************************");
                          Slog.e("System", "************ Failure starting system services", ex);
                          throw ex;
                      } finally {
                          t.traceEnd(); // StartServices
                      }
                  }
              	//(4)other服务启动
                  private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
                          //(5)wifi服务启动
                          if (context.getPackageManager().hasSystemFeature(
                                  PackageManager.FEATURE_WIFI)) {
                              // Wifi Service must be started first for wifi-related services.
                              t.traceBegin("StartWifi");  //(6)刚开机可以看到这些日志
                              mSystemServiceManager.startServiceFromJar(
                                      WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                              t.traceEnd();
                              t.traceBegin("StartWifiScanning");
                              mSystemServiceManager.startServiceFromJar(
                                      WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
                              t.traceEnd();
                          }
                          。。。
                  }
              }
              

              2、WifiService

              wifi服务类,并不是对外暴露的,对接的是SystemServer

              packages\modules\Wifi\service\java\com\android\server\wifi\WifiService.java

              public final class WifiService extends SystemService {
                  
                  private final WifiServiceImpl mImpl;
              	@Override
                  public void onBootPhase(int phase) {
                      if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
                          mImpl.checkAndStartWifi(); // (1)检查是否需要启动wifi
                      } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
                          mImpl.handleBootCompleted();
                      }
                  }
              }
              

              3、WifiServiceImpl

              wifi 启动的具体实现类,对接的是WifiManager 接口方法。

              packages\modules\Wifi\service\java\com\android\server\wifi\WifiServiceImpl.java

              public class WifiServiceImpl extends BaseWifiService {
                  private static final String TAG = "WifiService";
              	
              	// (1)检查是否需要启动wifi
              	public void checkAndStartWifi() {
                      mWifiThreadRunner.post(() -> {
                  
                  		//这里有打印wifi是否需要启动,具体实现是判断Settings.Global.WIFI_ON
                  		//但是这个方法内并未使用这个属性
                          // Check if wi-fi needs to be enabled
                          boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
                          Log.i(TAG,"WifiService starting up with Wi-Fi " + (wifiEnabled ? "enabled" : "disabled"));
              ...
                          mActiveModeWarden.start(); //(2)在这里判断是否开启
                          registerForCarrierConfigChange();
                          mWifiInjector.getAdaptiveConnectivityEnabledSettingObserver().initialize();
                          mIsWifiServiceStarted = true;
                      });
                  }
              }
              

              4、ActiveModeWarden

              wifi 状态处理,比较中间的

              packages\modules\Wifi\service\java\com\android\server\wifi\ActiveModeWarden.java

              public class ActiveModeWarden {
              	private static final String TAG = "WifiActiveModeWarden";
                  private final WifiController mWifiController;
                  
                  /** Begin listening to broadcasts and start the internal state machine. */
                  //(1)ActiveModeWarden.start
                  public void start() {
                  ...
                  	//(2) 调用Controller 状态机 start
              		mWifiController.start();
                  }
                  private class WifiController extends StateMachine {
                      private static final String TAG = "WifiController";
              		@Override
                      public void start() {
                          boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
                          boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
                          boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();
                          boolean isLocationModeActive = mWifiPermissionsUtil.isLocationModeEnabled();
              			
              			//(3) 这里也有打开wifi 是否需要开启wifi的日志
                          log("isAirplaneModeOn = " + isAirplaneModeOn
                                  + ", isWifiEnabled = " + isWifiEnabled
                                  + ", isScanningAvailable = " + isScanningAlwaysAvailable
                                  + ", isLocationModeActive = " + isLocationModeActive);
                                  
                          ActiveModeManager.ClientRole role = getRoleForPrimaryOrScanOnlyClientModeManager();
                          if (role == ROLE_CLIENT_PRIMARY) { //**(4)这个比较隐蔽,wifi开启是开启就是进入这里
                               startPrimaryClientModeManager(mLastPrimaryClientModeManagerRequestorWs);
                              setInitialState(mEnabledState);
                          } else if (role == ROLE_CLIENT_SCAN_ONLY) {
                              startScanOnlyClientModeManager(mLastScanOnlyClientModeManagerRequestorWs);
                              setInitialState(mEnabledState);
                          } else { //如果是不需要开启wifi,就是默认进入Disabled状态
                              setInitialState(mDisabledState);
                          }
                          mWifiMetrics.noteWifiEnabledDuringBoot(mSettingsStore.isWifiToggleEnabled());
                          // Initialize the lower layers before we start.
                          mWifiNative.initialize();
                          super.start();
                      }
                  }
                  	//(5) 具体的处理方法 startPrimaryOrScanOnlyClientModeManager
                  private boolean startPrimaryOrScanOnlyClientModeManager(WorkSource requestorWs) {
                      //(6)这里其实是判断了wifi_on那个Settings属性
                      ActiveModeManager.ClientRole role = getRoleForPrimaryOrScanOnlyClientModeManager();
                      if (role == ROLE_CLIENT_PRIMARY) { //(7)wifi 打开是进这里
                          return startPrimaryClientModeManager(requestorWs);
                      } else if (role == ROLE_CLIENT_SCAN_ONLY) {
                          return startScanOnlyClientModeManager(requestorWs);
                      } else {
                          return false;
                      }
                  }
              	
              	// (8)继续追踪方法
                  private boolean startPrimaryClientModeManager(WorkSource requestorWs) {
                      Log.d(TAG, "Starting primary ClientModeManager in connect mode");
                      //(9)这里创建了 ConcreteClientModeManager 对象,看起来没做啥,其实创建对象会做事情
              		ConcreteClientModeManager manager = mWifiInjector.makeClientModeManager(
                              new ClientListener(), requestorWs, ROLE_CLIENT_PRIMARY, mVerboseLoggingEnabled);
              				mClientModeManagers.add(manager); //连接对象被接入队列管理,可以不用关注,断开会被移除
                      mLastPrimaryClientModeManagerRequestorWs = requestorWs;
                      return true;
                  }
              }
              

              上面第4点看到,wifi开启是调用到 startPrimaryClientModeManager 方法和上面正常开启wifi调用到的第3步的ActiveModeWarden.wifiToggled里面后面调用到的方法是一个方法。

              所以往后的流程接着往ConcreteClientModeManager看就可以看到了。

              三、其他

              1、Android13 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 往下
              

              Android11 完整流程图:

              Android13 Wifi启动流程分析

              Android13 完整流程图:

              Android13 Wifi启动流程分析

              不同Android11 部分用黄色标记出来了。

              其实正常情况,流程大多是没啥用处的,除非有特殊需求要需要改,但是wifi异常分析是经常遇到的,这种情况就要查看日志,需要找到关键时间点,进一步确定异常原因了,下面的日志可能会有一些帮助。

              2、日志查看

              关键字和可以查看到的关键信息
              关键字 : 关键信息
              WifiService:查看WifiServiceImpl调用信息,一些api调用日志和wifi 开关日志
              WifiController:ActiveModeWarden 内部状态机的一些信息
              WifiActiveModeWarden:ActiveModeWarden 过程日志
              WifiClientModeManager:ConcreteClientModeManager的过程日志
              WifiNative:底层调用情况日志,异常情况会有明显日志
              (底层)
              HalDevMgr:HalDeviceManager 过程日志,和异常提示
              WifiVendorHal:Hal过程日志和异常日志
              android.hardware.wifi:底层hardware包相关日志
              

              一般情况关键日志主要看 WifiService 和 WifiNative , 根据发生问题时间点再仔细研究即可。

              多个日志打印的命令:

              logcat | grep -E "WifiService|WifiController|WifiActiveModeWarden|WifiClientModeManager|WifiNative"
              

              测试打印部分日志如下:

              正常开启wifi日志:
              //(1)清除一下日志
              bsp:/ $ logcat -c
              //(2)过滤关键字日志
              bsp:/ $logcat | grep -E "WifiService|WifiController|WifiActiveModeWarden|WifiClientModeManager|WifiNative" 
              //(3)打开wifi 的应用包名和uid, uid =1000 表示普通的系统应用, enable=true 表示打开
              12-21 16:57:37.448   979  1393 I WifiService: setWifiEnabled package=com.skg.settings uid=1000 enable=true isPrivileged=true
              //(4)其他一下状态信息
              12-21 16:57:37.453   979  1275 D WifiActiveModeWarden: Starting primary ClientModeManager in connect mode
              12-21 16:57:37.453   979  1275 D WifiController: DisabledState.exit()
              12-21 16:57:37.453   979  1275 D WifiController: EnabledState.enter()
              //(5) wlan0 节点开始打开
              12-21 16:57:37.582   979  1275 I WifiNative: Successfully setup Iface:{Name=wlan0,Id=13,Type=STA_SCAN}
              12-21 16:57:37.585   979  1275 D WifiClientModeManager[wlan0]: entering StartedState
              12-21 16:57:37.599   979  1275 D WifiActiveModeWarden: setting wifi state to: 2
              //(6)系统发送wifi 开关状态广播, 说明系统发出wifi 开关状态变化的广播 WIFI_STATE_CHANGED_ACTION 是 ConcreteClientModeManager 发出的
              12-21 16:57:37.600   979  1275 D WifiClientModeManager[wlan0]: Sending broadcast=WIFI_STATE_CHANGED_ACTION EXTRA_WIFI_STATE=2 EXTRA_PREVIOUS_WIFI_STATE=1
              //(7) 应用查询wifi状态日志, uid=1000 是uid系统apk
              12-21 16:57:37.610   979  9543 I WifiService: getWifiEnabledState uid=10097
              12-21 16:57:37.637   979 24139 I WifiService: getWifiEnabledState uid=1000
              12-21 16:57:37.641   979 24139 I WifiService: getWifiEnabledState uid=1000
              //(8) wlan0 节点成功打开
              12-21 16:57:37.674   979  1275 I WifiNative: Successfully switched to connectivity mode on iface=Iface:{Name=wlan0,Id=13,Type=STA_CONNECTIVITY}
              //(9)中间一些信息
              12-21 16:57:37.674   979  1275 D WifiClientModeManager[wlan0]: entering ConnectModeState, starting ClientModeImpl
              12-21 16:57:37.679   979  1275 V WifiClientModeManager[wlan0]: ClientModeManager started in role: Role: ROLE_CLIENT_PRIMARY, RequestorWs: WorkSource{1000 com.skg.settings}, ModeListener: com.android.server.wifi.ActiveModeWarden$ClientListener@ded9fb6
              12-21 16:57:37.685   979  1275 V WifiActiveModeWarden: ModeManager added ConcreteClientModeManager{id=10580945 iface=wlan0 role=ROLE_CLIENT_PRIMARY}
              //(11)设置  CountryCode ,00 应该是无效的,CN,US 那些才有用的,不过wifi 开启对CountryCode 没有要求,热点才有要求
              12-21 16:57:37.695   979  1275 D WifiNative: onSetCountryCodeSucceeded: 00
              12-21 16:57:37.699   979  1275 V WifiActiveModeWarden: Primary ClientModeManager changed from null to ConcreteClientModeManager{id=10580945 iface=wlan0 role=ROLE_CLIENT_PRIMARY}
              //(12) wifi 完成打开的状态
              12-21 16:57:37.699   979  1275 D WifiActiveModeWarden: setting wifi state to: 3
              

              这里看到wifi 从打开标识 setWifiEnabled 开始,到完成打开一般只用一秒不到。

              重点可以关注:WifiService 和 WifiNative 相关的日志,其中 WifiService 在后续扫描过程也是会有一些日志。

              正常关闭wifi日志:
              bsp:/ $logcat | grep -E "WifiService|WifiController|WifiActiveModeWarden|WifiClientModeManager|WifiNative"
              //(1)关闭 wifi 的应用包名和uid, uid =1000 表示普通的系统应用, enable=false 表示关闭
              12-21 18:24:01.039   967  1554 I WifiService: setWifiEnabled package=com.skg.settings uid=1000 enable=false isPrivileged=true
              //(2)状态机那些准备关闭wifi
              12-21 18:24:01.044   967  1212 D WifiActiveModeWarden: Shutting down all client mode managers
              12-21 18:24:01.051   967  1212 D WifiClientModeManager[wlan0]:  currentstate: ConnectModeState
              //(3)进入正在关闭wifi状态0
              12-21 18:24:01.055   967  1212 D WifiActiveModeWarden: setting wifi state to: 0
              //(4)发送广播 正在关闭WiFi,EXTRA_WIFI_STATE=0 当前状态是正在关闭, EXTRA_PREVIOUS_WIFI_STATE=3 之前状态是打开
              12-21 18:24:01.059   967  1212 D WifiClientModeManager[wlan0]: Sending broadcast=WIFI_STATE_CHANGED_ACTION EXTRA_WIFI_STATE=0 EXTRA_PREVIOUS_WIFI_STATE=3
              12-21 18:24:01.065   967  1212 D WifiClientModeManager[wlan0]: The target role change info null
              12-21 18:24:01.065   967  1212 D WifiClientModeManager[wlan0]: Continue to stop wifi
              //(5)进入已关闭wifi状态1
              12-21 18:24:01.065   967  1212 D WifiActiveModeWarden: setting wifi state to: 1
              //发送广播 正在已WiFi,EXTRA_WIFI_STATE=1 是当前进入已关闭wifi状态,EXTRA_PREVIOUS_WIFI_STATE=0 表示上一个状态是正在关闭wifi状态
              12-21 18:24:01.066   967  1212 D WifiClientModeManager[wlan0]: Sending broadcast=WIFI_STATE_CHANGED_ACTION EXTRA_WIFI_STATE=1 EXTRA_PREVIOUS_WIFI_STATE=0
              //(6)移除节点信息
              12-21 18:24:01.094   967  1212 D WifiNative: IfaceManager#removeIface: id=1, pre-map={1=Iface:{Name=wlan0,Id=1,Type=STA_CONNECTIVITY}}
              12-21 18:24:01.127   967  1212 D WifiClientModeManager[wlan0]: STA iface wlan0 was destroyed, stopping client mode
              12-21 18:24:01.127   967  1212 W WifiClientModeManager[wlan0]: Received mWifiNativeInterfaceCallback.onDestroyed callback when no ClientModeImpl instance is active.
              //(7)完成节点关闭
              12-21 18:24:01.127   967  1212 I WifiNative: Successfully torn down Iface:{Name=wlan0,Id=1,Type=STA_CONNECTIVITY}
              12-21 18:24:01.128   967  1212 I WifiNative: Successfully initiated teardown for iface=wlan0
              
              缺少wifi硬件模组是开启wifi日志:
              bsp:/ $logcat | grep -E "WifiService|WifiController|WifiActiveModeWarden|WifiClientModeManager|WifiNative"
              //(1)打开wifi 的应用包名和uid, uid =1000 表示普通的系统应用, enable=true 表示打开
              12-21 18:56:50.905   967  2954 I WifiService: setWifiEnabled package=com.skg.settings uid=1000 enable=true isPrivileged=true
              //(2)准备打开 wifi
              12-21 18:56:50.907   967  1212 D WifiActiveModeWarden: Starting primary ClientModeManager in connect mode
              12-21 18:56:50.908   967  1212 D WifiController: DisabledState.exit()
              12-21 18:56:50.908   967  1212 D WifiController: EnabledState.enter()
              //(3)无法打开,进入闲置状态
              12-21 18:56:50.908   967  1212 D WifiClientModeManager[unknown]: entering IdleState
              12-21 18:56:50.966   967  1212 D WifiNative: IfaceManager#allocateIface: type=2, pre-map={}
              //(4)Hal 层有异常 died
              12-21 18:56:50.969   967  1212 I WifiNative: Vendor HAL died. Cleaning up internal state.
              //(5)Hal 层无法创建节点
              12-21 18:56:50.970   967  1212 E WifiNative: Failed to create iface in vendor HAL
              //(6)移除节点
              12-21 18:56:50.970   967  1212 D WifiNative: IfaceManager#removeIface: id=2, pre-map={2=Iface:{Name=null,Id=2,Type=STA_SCAN}}
              12-21 18:56:50.970   967  1212 E WifiClientModeManager[unknown]: Failed to create ClientInterface. Sit in Idle
              12-21 18:56:50.970   967  1212 E WifiActiveModeWarden: ClientModeManager start failed!ConcreteClientModeManager{id=6808585 iface=null role=null}
              12-21 18:56:50.970   967  1212 V WifiActiveModeWarden: ModeManager removed ConcreteClientModeManager{id=6808585 iface=null role=null}
              12-21 18:56:50.978   967  1212 E WifiActiveModeWarden: One of the native daemons died. Triggering recovery
              12-21 18:56:50.979   967  1212 E WifiSelfRecovery: Triggering recovery for reason: WifiNative Failure
              12-21 18:56:50.979   967  1212 E WifiSelfRecovery: Restarting wifi for reason: WifiNative Failure
              12-21 18:56:50.979   967  1212 D WifiController: STA disabled, return to DisabledState.
              //(7)有可能多次循环该异常日志
              12-21 18:56:50.979   967  1212 D WifiController: EnabledState.exit()
              12-21 18:56:50.979   967  1212 D WifiController: DisabledState.enter()
              12-21 18:56:50.979   967  1212 D WifiController: Recovery triggered, already in disabled state
              12-21 18:56:50.995   967  1212 I WifiNative: Vendor HAL died. Cleaning up internal state.
              12-21 18:56:50.995   967  1212 E WifiActiveModeWarden: One of the native daemons died. Triggering recovery
              12-21 18:56:50.995   967  1212 E WifiSelfRecovery: Triggering recovery for reason: WifiNative Failure
              12-21 18:56:50.995   967  1212 E WifiSelfRecovery: Restarting wifi for reason: WifiNative Failure
              12-21 18:56:50.995   967  1212 D WifiController: Recovery triggered, already in disabled state
              12-21 18:56:52.981   967  1212 D WifiController: Recovery in progress, start wifi
              12-21 18:56:52.984   967  1212 D WifiActiveModeWarden: Starting primary ClientModeManager in connect mode
              12-21 18:56:52.985   967  1212 D WifiController: DisabledState.exit()
              12-21 18:56:52.985   967  1212 D WifiController: EnabledState.enter()
              12-21 18:56:52.985   967  1212 D WifiClientModeManager[unknown]: entering IdleState
              。。。
              

              重新测试看从(2)准备打开到(3)异常情况,查看整个logcat日志,发现还有部分底层的打印:

              12-21 19:14:26.660   967  1212 D HalDevMgr: initIWifiIfNecessary
              12-21 19:14:26.664   967  1212 I android_os_HwBinder: HwBinder: Starting thread pool for getting: android.hardware.wifi@1.0::IWifi/default
              12-21 19:14:26.666   442   442 I android.hardware.wifi@1.0-service-lazy: Wifi HAL stopped
              12-21 19:14:26.667   967  1212 I WifiVendorHal: Device Manager onStatusChanged. isReady(): false, isStarted(): false
              12-21 19:14:26.667   967  1212 I WifiNative: Vendor HAL died. Cleaning up internal state.
              

              3、wifi开关状态值

              从WifiManager.java 代码看wifi 开关、关闭是有过程状态的:

                  /**
                   * The lookup key for an int that indicates whether Wi-Fi is enabled,
                   * disabled, enabling, disabling, or unknown.  Retrieve it with
                   * {@link android.content.Intent#getIntExtra(String,int)}.
                   *
                   * @see #WIFI_STATE_DISABLED //1
                   * @see #WIFI_STATE_DISABLING //0 
                   * @see #WIFI_STATE_ENABLED //3
                   * @see #WIFI_STATE_ENABLING //2
                   * @see #WIFI_STATE_UNKNOWN //4
                   */
                  public static final String EXTRA_WIFI_STATE = "wifi_state";
                  
                   /**
                   * Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
                   * enabling, disabling, or unknown. One extra provides this state as an int.
                   * Another extra provides the previous state, if available.  No network-related
                   * permissions are required to subscribe to this broadcast.
                   *
                   * 

              This broadcast is not delivered to manifest receivers in * applications that target API version 26 or later. * * @see #EXTRA_WIFI_STATE //广播的wifi状态值数据 * @see #EXTRA_PREVIOUS_WIFI_STATE */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";

              这里可以看到从wifi开关状态广播变化中的额外信息可以看到:

              1 是关闭状态,3是打开状态,0 是正在关闭,2是正在打开;

              这几个状态变化的过程,正常都是有广播的。

              4、之前写的一些wifi相关的知识

              汇总:

              https://so.csdn.net/so/search?q=wifi&t=blog&u=wenzhi20102321

              Android10 系统应用wifi连接和静态ip代理设置:

              https://blog.csdn.net/wenzhi20102321/article/details/123675077

              Android adb shell svc 知识详解:

              https://blog.csdn.net/wenzhi20102321/article/details/132779708

              Android无线Wifi开发:

              https://blog.csdn.net/wenzhi20102321/article/details/53871216

              Android13 wifi状态问题分析:

              https://blog.csdn.net/wenzhi20102321/article/details/130411508

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]