基于 原生的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到底层。