Android S Wi-Fi 打开流程(一)

基于 原生的Android S代码: http://aospxref.com/android-13.0.0_r3/

packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java

183      public boolean onSwitchToggled(boolean isChecked) {
184          //Do nothing if called as a result of a state machine event
185          if (mStateMachineEvent) {
186              return true;
187          }
188          // Show toast message if Wi-Fi is not allowed in airplane mode
189          if (isChecked && !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_WIFI)) {
190              Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
191              // Reset switch to off. No infinite check/listener loop.
192              mSwitchWidget.setChecked(false);
193              return false;
194          }
195  
196          if (isChecked) {
197              mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_ON);
198          } else {
199              // Log if user was connected at the time of switching off.
200              mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_OFF,
201                      mConnected.get());
202          }
203          if (!mWifiManager.setWifiEnabled(isChecked)) {    ---> 打开 Wi-Fi
204              // Error
205              mSwitchWidget.setEnabled(true);
206              Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
207          }
208          return true;
209      }
210  }

具体的可以看下代码,主要流程如下:
packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
setWifiEnabled —> setWifiEnabledInternal —> mActiveModeWarden.wifiToggled(new WorkSource(callingUid, packageName));

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

668      /** Wifi has been toggled. */
669      public void wifiToggled(WorkSource requestorWs) {
670          mWifiController.sendMessage(WifiController.CMD_WIFI_TOGGLED, requestorWs);
671      }

看下状态机:

1595          WifiController() {
1598              DefaultState defaultState = new DefaultState();
1599              addState(defaultState); {
1600                  addState(mDisabledState, defaultState);
1601                  addState(mEnabledState, defaultState);
1602              }

再看下初始的是哪个状态,这里我们看到这个地方有个初始化,很容易会根据这个误以为初始化状态是 setInitialState(mEnabledState)
需要仔细看下,这个start()方法是何时被调用的,追下代码发现是在:SystemService.PHASE_SYSTEM_SERVICES_READY阶段,也就是开机初始化的时候会根据之前的Wi-Fi状态去做些判断,而我们此时默认未开启,那初始状态就是 setInitialState(mDisabledState)

1656          public void start() {
1657              boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
1658              boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
1659              boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();
1660              boolean isLocationModeActive = mWifiPermissionsUtil.isLocationModeEnabled();
1661  
1662              log("isAirplaneModeOn = " + isAirplaneModeOn
1663                      + ", isWifiEnabled = " + isWifiEnabled
1664                      + ", isScanningAvailable = " + isScanningAlwaysAvailable
1665                      + ", isLocationModeActive = " + isLocationModeActive);
1666  
1667              // Initialize these values at bootup to defaults, will be overridden by API calls
1668              // for further toggles.
1669              mLastPrimaryClientModeManagerRequestorWs = mFacade.getSettingsWorkSource(mContext);
1670              mLastScanOnlyClientModeManagerRequestorWs = INTERNAL_REQUESTOR_WS;   ---> 指的是 Process.WIFI_UID
1671              ActiveModeManager.ClientRole role = getRoleForPrimaryOrScanOnlyClientModeManager();
1672              if (role == ROLE_CLIENT_PRIMARY) {   --->Wi-Fi 模式,然后构造相应的 ClientModeManager
1673                  startPrimaryClientModeManager(mLastPrimaryClientModeManagerRequestorWs);
1674                  setInitialState(mEnabledState);
1675              } else if (role == ROLE_CLIENT_SCAN_ONLY) {   ---> 这个理解仅仅扫描模式
1676                  startScanOnlyClientModeManager(mLastScanOnlyClientModeManagerRequestorWs);
1677                  setInitialState(mEnabledState);
1678              } else {   ---> 不属于上面两种的任何一种
1679                  setInitialState(mDisabledState);
1680              }
1681              mWifiMetrics.noteWifiEnabledDuringBoot(mSettingsStore.isWifiToggleEnabled());
1682  
1683              // Initialize the lower layers before we start.
1684              mWifiNative.initialize();
1685              super.start();
1686          }

			// 看下处理这个消息的地方:
1936          class DisabledState extends BaseState {
1952              @Override
1953              public boolean processMessageFiltered(Message msg) {
1954                  switch (msg.what) {
1955                      case CMD_WIFI_TOGGLED:  ---> 处理这个消息
1956                      case CMD_SCAN_ALWAYS_MODE_CHANGED:
1957                          handleStaToggleChangeInDisabledState((WorkSource) msg.obj);
1958                          break;
				}
				
1909          private void handleStaToggleChangeInDisabledState(WorkSource requestorWs) {
1910              if (shouldEnableSta()) {
1911                  startPrimaryOrScanOnlyClientModeManager(requestorWs);
1912                  transitionTo(mEnabledState);
1913              }
1914          }

1112      private boolean startPrimaryOrScanOnlyClientModeManager(WorkSource requestorWs) {
1113          ActiveModeManager.ClientRole role = getRoleForPrimaryOrScanOnlyClientModeManager();
1114          if (role == ROLE_CLIENT_PRIMARY) {   ---> 开启Wi-Fi 是这个角色
1115              return startPrimaryClientModeManager(requestorWs);
1116          } else if (role == ROLE_CLIENT_SCAN_ONLY) {
1117              return startScanOnlyClientModeManager(requestorWs);
1118          } else {
1119              return false;
1120          }
1121      }

1097      /** 
1098       * Method to enable a new primary client mode manager in connect mode.
1099       */
1100      private boolean startPrimaryClientModeManager(WorkSource requestorWs) {
1101          Log.d(TAG, "Starting primary ClientModeManager in connect mode");
              // 主要是去构造一个clientModeManager,其实就是[ new ConcreteClientModeManager]
1102          ConcreteClientModeManager manager = mWifiInjector.makeClientModeManager(
1103                  new ClientListener(), requestorWs, ROLE_CLIENT_PRIMARY, mVerboseLoggingEnabled);
1104          mClientModeManagers.add(manager);
1105          mLastPrimaryClientModeManagerRequestorWs = requestorWs;
1106          return true;
1107      }

/packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
接着上面的地方看下new出来的:

151      ConcreteClientModeManager(
152              Context context, @NonNull Looper looper, Clock clock,
153              WifiNative wifiNative, @NonNull Listener<ConcreteClientModeManager> listener,
154              WifiMetrics wifiMetrics,
155              WakeupController wakeupController, WifiInjector wifiInjector,
156              SelfRecovery selfRecovery, WifiGlobals wifiGlobals,
157              DefaultClientModeManager defaultClientModeManager, long id,
158              @NonNull WorkSource requestorWs, @NonNull ClientRole role,
159              @NonNull ClientModeManagerBroadcastQueue broadcastQueue,
160              boolean verboseLoggingEnabled) {
161          mContext = context;
162          mClock = clock;
163          mWifiNative = wifiNative;
164          mModeListener = listener;
165          mWifiMetrics = wifiMetrics;
166          mWakeupController = wakeupController;
167          mWifiInjector = wifiInjector;
168          mStateMachine = new ClientModeStateMachine(looper);
169          mDeferStopHandler = new DeferStopHandler(looper);
170          mSelfRecovery = selfRecovery;
171          mWifiGlobals = wifiGlobals;
172          mDefaultClientModeManager = defaultClientModeManager;
173          mId = id;
174          mTargetRoleChangeInfo = new RoleChangeInfo(role, requestorWs, listener);
175          mBroadcastQueue = broadcastQueue;
176          enableVerboseLogging(verboseLoggingEnabled);
			 // 这个消息会在初始 mIdleState 状态里处理
177          mStateMachine.sendMessage(ClientModeStateMachine.CMD_START, mTargetRoleChangeInfo);  
178      }

825          private class IdleState extends State {
826              @Override
827              public void enter() {
828                  Log.d(getTag(), "entering IdleState");
829                  mClientInterfaceName = null;
830                  mIfaceIsUp = false;
831              }

843              @Override
844              public boolean processMessage(Message message) {
845                  switch (message.what) {
846                      case CMD_START:
847                          // Always start in scan mode first.
848                          RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
                             // 这个就是比较熟悉的方法了,去底层初始化加载驱动等,待会我们再看
849                          mClientInterfaceName = mWifiNative.setupInterfaceForClientInScanMode(
850                                  mWifiNativeInterfaceCallback, roleChangeInfo.requestorWs);
851                          if (TextUtils.isEmpty(mClientInterfaceName)) {
852                              Log.e(getTag(), "Failed to create ClientInterface. Sit in Idle");
853                              takeBugReportInterfaceFailureIfNeeded(
854                                      "Wi-Fi scan STA interface HAL failure");
855                              mModeListener.onStartFailure(ConcreteClientModeManager.this);
856                              break;
857                          }
858                          if (roleChangeInfo.role instanceof ClientConnectivityRole) {
859                              sendMessage(CMD_SWITCH_TO_CONNECT_MODE, roleChangeInfo);  ---> 发送消息
860                              transitionTo(mStartedState);   ---> 切换到这个状态里处理消息
861                          } else {
862                              mScanRoleChangeInfoToSetOnTransition = roleChangeInfo;
863                              transitionTo(mScanOnlyModeState);
864                          }
865                          break;

874          private class StartedState extends State {
892              public void enter() {
893                  Log.d(getTag(), "entering StartedState");
894                  mIfaceIsUp = false;
895                  mIsStopped = false;
896                  onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName));
897              }

899              @Override
900              public boolean processMessage(Message message) {
901                  switch (message.what) {
902                      case CMD_START:
903                          // Already started, ignore this command.
904                          break;
905                      case CMD_SWITCH_TO_CONNECT_MODE: {   ---> 处理这个消息
906                          RoleChangeInfo roleChangeInfo = (RoleChangeInfo) message.obj;
907                          updateConnectModeState(roleChangeInfo.role,   ---> 广播告知状态
908                                  WifiManager.WIFI_STATE_ENABLING,
909                                  WifiManager.WIFI_STATE_DISABLED);
910                          if (!mWifiNative.switchClientInterfaceToConnectivityMode(
911                                  mClientInterfaceName, roleChangeInfo.requestorWs)) {
912                              updateConnectModeState(roleChangeInfo.role,
913                                      WifiManager.WIFI_STATE_UNKNOWN,
914                                      WifiManager.WIFI_STATE_ENABLING);
915                              updateConnectModeState(roleChangeInfo.role,
916                                      WifiManager.WIFI_STATE_DISABLED,
917                                      WifiManager.WIFI_STATE_UNKNOWN);
918                              takeBugReportInterfaceFailureIfNeeded(
919                                      "Wi-Fi STA interface HAL failure");
920                              mModeListener.onStartFailure(ConcreteClientModeManager.this);
921                              break;
922                          }
923                          // Role set in the enter of ConnectModeState.
924                          mConnectRoleChangeInfoToSetOnTransition = roleChangeInfo;
925                          transitionTo(mConnectModeState);  ---> 转到这个状态机
926                          break;
927                      }

主要看下这个就知道广播的内容,新状态和当前的状态,这里有如下几个状态:
[ WIFI_STATE_DISABLING、 WIFI_STATE_DISABLED
WIFI_STATE_ENABLING、 WIFI_STATE_ENABLED
WIFI_STATE_UNKNOWN ]

657      private void updateConnectModeState(ClientRole role, int newState, int currentState) {
671          final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
672          intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
673          intent.putExtra(WifiManager.EXTRA_WIFI_STATE, newState);
674          intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, currentState);
675          String summary = "broadcast=WIFI_STATE_CHANGED_ACTION"
676                  + " EXTRA_WIFI_STATE=" + newState
677                  + " EXTRA_PREVIOUS_WIFI_STATE=" + currentState;
678          if (mVerboseLoggingEnabled) Log.d(getTag(), "Queuing " + summary);
}

接下来看下 状态机切换到:ConnectModeState 中:

1031      private class ConnectModeState extends State {
1032              @Override
1033              public void enter() {
1034                  Log.d(getTag(), "entering ConnectModeState, starting ClientModeImpl");
1035                  if (mClientInterfaceName == null) {
1036                      Log.e(getTag(), "Supposed to start ClientModeImpl, but iface is null!");
1037                  } else {
1038                      if (mClientModeImpl != null) {
1039                          Log.e(getTag(), "ConnectModeState.enter(): mClientModeImpl is already "
1040                                  + "instantiated?!");
1041                      }
1042                      mClientModeImpl = mWifiInjector.makeClientModeImpl(
1043                              mClientInterfaceName, ConcreteClientModeManager.this,
1044                              mVerboseLoggingEnabled);
1045                      mClientModeImpl.setShouldReduceNetworkScore(mShouldReduceNetworkScore);
1046                  }
1047                  if (mConnectRoleChangeInfoToSetOnTransition == null
1048                          || !(mConnectRoleChangeInfoToSetOnTransition.role
1049                          instanceof ClientConnectivityRole)) {
1050                      Log.wtf(TAG, "Unexpected mConnectRoleChangeInfoToSetOnTransition: "
1051                              + mConnectRoleChangeInfoToSetOnTransition);
1052                      // Should never happen, but fallback to primary to avoid a crash.
1053                      mConnectRoleChangeInfoToSetOnTransition =
1054                              new RoleChangeInfo(ROLE_CLIENT_PRIMARY);
1055                  }
1056                  // 成功后更新
1057                  // Could be any one of possible connect mode roles.
1058                  setRoleInternalAndInvokeCallback(mConnectRoleChangeInfoToSetOnTransition);
1059                  updateConnectModeState(mConnectRoleChangeInfoToSetOnTransition.role,
1060                          WIFI_STATE_ENABLED, WIFI_STATE_ENABLING);
1061              }
1062  

至此第一部分暂时记录到这里,接下来会记录 上面提到的 wifiNative到底层。

你可能感兴趣的:(Wi-Fi,android,java,开发语言)