Android WiFi

  1. WiFi Enabled
    1.1 WiFi enable 3 ways.
    1.1.1 Enable WiFi in SetupWizard.

OnCreate()
if (isFirstEnterWifiSetupWizard == FIRST_ENTER && mSetupWizardCheck == 0) {
if (“ON”.equals(SecProductFeature_WLAN.SEC_PRODUCT_FEATURE_WLAN_CONFIG_DEF_STATUS) && !WIFI_OFF) {
mWifiManager.setWifiEnabled(true);
} else {
mWifiManager.setWifiEnabled(false);
}
private void updateLayoutMargin(Configuration newConfig)
mWifiEnabler = new WifiEnabler(this, mSwitchBar);

1.1.2 Enable Wifi in Notification

WifiTile.java
protected void handleClick()
//MultiState.OFF ==2
if (mWifiManager != null
&& mWifiManager.setWifiEnabled(mState.value == MultiState.OFF)) {
Log.d(TW_TAG, “onClick setWifiEnabled”);

        if(Feature.mQsAnimationIcon) {
            if (mState.value == MultiState.OFF)
                mIconOn.setAllowAnimation(true);
            else {
                mIconOff.get(0).setAllowAnimation(true);
            }
        }   
        if (SecProductFeature_KNOX.SEC_PRODUCT_FEATURE_KNOX_SUPPORT_MDM) {
         AuditLog.log(AuditLog.NOTICE, AuditLog.AUDIT_LOG_GROUP_APPLICATION, true,
                    android.os.Process.myPid(), this.getClass().getSimpleName(),
                    AuditEvents.WIFI_ENABLING );
       }
    } else {
        refreshState(mState.value);
        Slog.d(TW_TAG, "!setWifiEnabled");
        if (SecProductFeature_KNOX.SEC_PRODUCT_FEATURE_KNOX_SUPPORT_MDM) {
             AuditLog.log(AuditLog.NOTICE, AuditLog.AUDIT_LOG_GROUP_APPLICATION, true,
                       android.os.Process.myPid(), this.getClass().getSimpleName(),
                       AuditEvents.WIFI_DISABLING );
        }
    }

    if (mState.value == MultiState.OFF) {
        WifiStatusReceiver.enableToShowWifiPickerDialog(true);
    }

Log
12-29 15:31:05.907 D 3529 STATUSBAR-WifiTile handleClick : 2, 1
12-29 15:31:05.947 D 3529 STATUSBAR-WifiTile onClick setWifiEnabled
12-29 15:31:05.947 D 3529 WifiStatusReceiver Want to show AP LIST:true
12-29 15:31:06.017 D 3529 STATUSBAR-WifiTile onReceive : android.net.wifi.WIFI_STATE_CHANGED

1.1.3 Enable WiFi in Settings

WifiSettings
public void onStart() {
// On/off switch is hidden for Setup Wizard (returns null)
if (!mSecSetupWizardMode && !mInPickerDialog && !mInOffloadDialog && mWifiEnabler == null && !mInSetupWizardWifiScreen) {
mWifiEnabler = createWifiEnabler();
}
}

/**
 * @return new WifiEnabler or null (as overridden by WifiSettingsForSetupWizard)
 */
/* package */ WifiEnabler createWifiEnabler() {
    if ((getActivity() instanceof SettingsActivity)) {
        final SettingsActivity activity = (SettingsActivity) getActivity();
        mSwitchBar = activity.getSwitchBar();
        return new WifiEnabler(activity, mSwitchBar);
    } else {
        return null;
    }

}

public void onResume() {
if (mWifiEnabler != null) {
mWifiEnabler.resume(activity);
}
}
WifiEnabler
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
setWifiEnable(isChecked);
}

private void setWifiEnable(boolean enable) {
    if (mWifiManager.isWifiEnabled() == enable)
        return;
    mSwitch.setEnabled(false);
    if (!mWifiManager.setWifiEnabled(enable)) {
        // Error
        mSwitch.setEnabled(true);
        if (mSwitchBar != null) {
            mSwitchBar.setChecked(false);
        }
        if (mSwitchHandler != null) {
            mSwitchHandler.sendEmptyMessage(SWITCH_DISABLED);
        }
        //Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
    }
}

1.1.4
1.2
2. Initialization for Wifi Module
2.1 Wifi Structure

2.2 WiFi Server Start
SystemServer
public static void main(String[] args) {
new SystemServer().run();
}

private void run() {
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
//startThemeService();
} catch (Throwable ex) {
Slog.e(“System”, “********************************”);
Slog.e(“System”, “** Failure starting system services”, ex);
throw ex;
}
}

private void startOtherServices() {
mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
if (SecProductFeature_WLAN.SEC_PRODUCT_FEATURE_WLAN_SUPPORT_HOTSPOT_20) {
mSystemServiceManager.startService(WIFI_HS20_SERVICE_CLASS);
}

            mSystemServiceManager.startService(
                        "com.android.server.wifi.WifiScanningService");

            mSystemServiceManager.startService("com.android.server.wifi.RttService");

//< RNTFIX:: Ethernet
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
SecProductFeature_COMMON.SEC_PRODUCT_FEATURE_COMMON_SUPPORT_ETHERNET) {
mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
try {
Slog.i(TAG, “Connectivity Service”);
connectivity = new ConnectivityService(
context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
networkStats.bindConnectivityManager(connectivity);
networkPolicy.bindConnectivityManager(connectivity);
} catch (Throwable e) {
reportWtf(“starting Connectivity Service”, e);
}
}

(1) ConnectivityService
ConnectivityService ‘s core role is to provide data connection management services. It can get information from NetworkStateTracker.
NetworkInfo():Describe a given type of network interface information, including the network connection, network type whether such information. (getTypeName() can return “WIFI” or “MOBILE”)
LinkProperties():Describe a network connection attribute information. Including the network address, gateway, DNS, such as set/get HTTP proxy attribute information.
NetworkCapabilities(): Describe the network interface state information, including bandwidth, delay, etc.
NetworkStateTracker(): It is an interface. BaseNetworkStateTracker() is base class. It is control and observe state of a specific network.

(2) WifiService
public WifiService(Context context) {
super(context);
mImpl = new WifiServiceImpl(context);
}

public final class WifiServiceImpl extends IWifiManager.Stub {
private class ClientHandler extends Handler{}
private class WifiStateMachineHandler extends Handler {}
public WifiServiceImpl(Context context) {
mTrafficPoller = new WifiTrafficPoller(mContext, this, mInterfaceName);
mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName, mTrafficPoller);

mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
mSettingsStore = new WifiSettingsStore(mContext);

HandlerThread wifiThread = new HandlerThread("WifiService");
wifiThread.start();
mClientHandler = new ClientHandler(wifiThread.getLooper());
mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
mWifiController = new WifiController(mContext, this, wifiThread.getLooper());

}

/**
* Check if Wi-Fi needs to be enabled and start
* if needed
*
* This function is used only at boot time
*/
public void checkAndStartWifi() {
/* Check if wi-fi needs to be enabled */
boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
mWifiController.start();
}
}
WifiServer Start Flow

Enabled WiFi flow

  1. Disabled Wifi

Explain for Chart:
(1) WifiService will sent message CMD_WIFI_TOGGLED.and WifiController ApStaDisableState deal with this message.
(2) WifiStateMachine will deal with CMD_STOP_SUPPLICANT. In WaitForP2pDisableState will sent CMD_DISABLE_P2P_REQ and deal with CMD_DISABLE_P2P_RSP. State change to SupplicantStoppingState.
(3) In SupplicantStoppingState, it will call handleNetworkDisconnect() to stop DHCP and clear some message. It will call WifiNative.stopSupplicant() to deal with “TERMINATE” order in wpa_supplicant.
(4) In WifiP2PService deal with WifiMonitor.stopMonitoring, WifiStateMachine receive SUP_DISCONNECTION_EVENT, process this message.
Usefully log:
3041 D WifiController: handleMessage: E msg.what=CMD_WIFI_TOGGLED
3041 D WifiController: processMsg: ApStaDisabledState
3025 D WifiStateMachine: handleMessage: E msg.what=CMD_STOP_SUPPLICANT
3025 D WifiStateMachine: processMsg: DisconnectedState
3025 D WifiStateMachine: processMsg: ConnectModeState
3025 D WifiStateMachine: processMsg: DriverStartedState
3025 D WifiStateMachine: processMsg: SupplicantStartedState
3025 D WifiStateMachine: transitionTo: destState=WaitForP2pDisableState
3025 D WifiStateMachine: handleMessage: E msg.what=CMD_DISABLE_P2P_RSP
3025 D WifiStateMachine: processMsg: WaitForP2pDisableState
3025 D WifiStateMachine: transitionTo: destState=SupplicantStoppingState
3025 D WifiStateMachine: setWifiState: disabled
3025 D WifiStateMachine: transitionTo: destState=InitialState

  1. Scan and connect AP
    4.1 WiFi Scan Flow

c
Explain for Chart:
(1) In WifiStateMachine process CMD_START_SCAN.
(2) WifiNative.scan deal with scan in wap_supplicant.
(3) WifiMonitor receive the message from wap_supplicant.
(4) WifiStateMachine process the those message, sendbroadcast, notify the interface to update AP list.
Usefully log:
3025 D WifiStateMachine: handleMessage: E msg.what=131143—- CMD_START_SCAN
3025 D WifiStateMachine: processMsg: DriverStartedState
3025 D WifiNative-wlan0: doBoolean: SCAN
8290 D WifiService: startScan by pid=3598, uid=1000
13617 D WifiMonitor: Event [IFNAME=wlan0 WPS-AP-AVAILABLE ]
3025 D WifiStateMachine: handleMessage: E msg.what=147461—- SCAN_RESULTS_EVENT
3025 D WifiStateMachine: processMsg: SupplicantStartedState
3025 D WifiNative-wlan0: doString: BSS RANGE=0- MASK=0x21987
3598 D WifiSettings: [updateAccessPoints] wifiState : 3

4.2 Connect AP

Explain for Chart:
(1) Mainly work is WifiManager.connect().WifiConfigStore.saveNetwok(config) is used for save AP to wpa_supplicant.conf. WifiConfigStore.selectNetwork(netId) is used for enable connecting AP. WifiNative.reconnect() sent the reconnect request to wpa_supplicant. You can refer the Figure1.
(2) wpa_supplicant continuous delivery CTRL-EVENT-STATE-CHANGE、ASSOCIATING、ASSOCIATED event, and WifiMonitor will parse event.
(3) After connection is successful between WLAN and AP, wpa_supplicant will sent CTRL-EVENT-CONNECTED event. After processed this event, enter get IP address part.
(4) Two ways to get IP address. One is static, the other is dynamic. This need interact with DhcpStateMachine.
(5) VerifyingLinkState verify the connection state. This function come true by WifiWatchdogStateMachine.
(6) Captive Portal is the authentication method. After captive check complete, the upper translation to ConnectedState.Connection ok.

Usefully log:
3025 D WifiStateMachine: handleMessage: E msg.what=151553—- CONNECT_NETWORK
21315 I wpa_supplicant: CTRL-EVENT-CONNECTED - Connection to 00:24:01:66:31:6d completed (auth) [id=0 id_str=]
21321 D WifiMonitor: Event [IFNAME=wlan0 CTRL-EVENT-CONNECTED - Connection to 00:24:01:66:31:6d completed (auth) [id=0 id_str=]]
3025 D WifiStateMachine: handleMessage: E msg.what=147459—- NETWORK_CONNECTION_EVENT
21387 D DhcpStateMachine: DHCP succeeded on wlan0
3025 D WifiStateMachine: DHCP successful
3042 D ConnectivityService: Captive portal check NetworkInfo: type: WIFI[], state: CONNECTING/CAPTIVE_PORTAL_CHECK, reason: (unspecified), extra: “dlink”, roaming: false, failover: false, isAvailable: true, isConnectedToProvisioningNetwork: false
3042 D ConnectivityService: handleCaptivePortalTrackerCheck: call captivePortalCheckComplete ni=NetworkInfo: type: WIFI[], state: CONNECTING/CAPTIVE_PORTAL_CHECK, reason: (unspecified), extra: “dlink”, roaming: false, failover: false, isAvailable: true, isConnectedToProvisioningNetwork: false
3025 D WifiStateMachine: transitionTo: destState=ConnectedState

  1. WifiStateMachine
    Learn about relationship about HSM.

(1) addState
(2) transitionTo
(3) obtainMessage
(4) sendMessage
(5) deferMessage
(6) enter()
(7) exit()
HSM is complex, you can treat it as tree. Two point: (1) About change the state, for example, ConnectModeState change to ScanModeState. The flow as blew: ConnectModeState.exit()->ScanModeState.enter. (2) If the current state can’t deal with this message, its father will handle it.

  1. IPC
    WifiManager and WifiServer.
### Android WIFI 配置与连接的技术解析 #### 1. Android WIFI 配置流程 在 Android 中,WIFI 的配置主要依赖于 `WifiManager` 类。通过该类可以完成网络的添加、移除以及状态监控等功能。以下是关于如何配置并连接到指定 WIFI 网络的关键步骤: - **创建 WIFI 配置对象** 使用 `WifiConfiguration` 对象来定义目标 WIFI 网络的信息,例如 SSID 和密码。 ```java WifiConfiguration config = new WifiConfiguration(); config.SSID = "\"" + ssid + "\""; // 注意 SSID 必须加双引号 config.preSharedKey = "\"" + password + "\""; ``` - **添加网络配置** 调用 `addNetwork()` 方法将新配置加入系统,并返回一个整数 ID 表示此配置项。 ```java int networkId = wifiManager.addNetwork(config); if (networkId == -1) { throw new Exception("Failed to add network configuration."); } ``` - **启用特定网络配置** 利用 `enableNetwork(networkId, true)` 启动刚刚添加的网络配置。 ```java boolean isEnabled = wifiManager.enableNetwork(networkId, true); if (!isEnabled) { throw new Exception("Failed to enable the specified network."); } ``` 以上操作完成后,需监听广播事件 `"WifiManager.NETWORK_STATE_CHANGED_ACTION"` 来确认是否成功连接至目标 WIFI[^1]。 --- #### 2. 删除当前已连接的 WIFI 配置信息 针对 Android 9.0 及更高版本,删除现有 WIFI 配置的功能被进一步优化。核心逻辑涉及调用 `removeNetwork(int netId)` 方法以清除指定网络条目,并最终通知系统刷新可用列表。 具体实现如下所示: ```java // 获取当前活动网络的 ID int currentNetId = getCurrentNetworkId(wifiManager); if (currentNetId != -1 && wifiManager.removeNetwork(currentNetId)) { Log.d(TAG, "Successfully removed the active network with ID: " + currentNetId); } else { Log.e(TAG, "Failed to remove the active network or no valid ID found."); } private int getCurrentNetworkId(WifiManager wifiManager) { List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks(); if (configuredNetworks != null) { for (WifiConfiguration config : configuredNetworks) { if (config.networkId >= 0 && wifiManager.getConnectionInfo().getNetworkId() == config.networkId) { return config.networkId; } } } return -1; // 如果未找到匹配的网络,则返回默认值 -1 } ``` 上述代码片段展示了如何定位当前正在使用的网络及其对应的唯一标识符(netId),随后执行移除动作[^2]。 --- #### 3. 实现动态检测 WIFI 是否处于连接状态 为了实时掌握设备的联网状况,可借助 `ConnectivityManager` 提供的服务接口查询活跃网络的状态。下面是一段用于验证 WIFI 是否正常工作的辅助函数: ```java public boolean isWifiConnected(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkCapabilities capabilities; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Network network = connectivityManager.getActiveNetwork(); capabilities = connectivityManager.getNetworkCapabilities(network); return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)); } else { @SuppressWarnings("deprecation") NetworkInfo info = connectivityManager.getActiveNetworkInfo(); return info != null && info.getType() == ConnectivityManager.TYPE_WIFI && info.isConnected(); } } ``` 这段程序兼容旧版 API 并支持现代化特性,能够适应不同平台环境下的需求变化[^4]。 --- #### 4. 关键服务组件剖析 深入研究底层架构可知,AndroidWIFI 功能由多个模块协同工作共同维护其运行机制。其中部分重要文件包括但不限于以下几个方面: - `SupplicantStaNetworkHalAidlImpl.java`: 定义了 STA 模式的 HAL 接口规范; - `SupplicantStaNetworkCallbackAidlImpl.java`: 处理来自 supplicant 层面的通知回调消息处理逻辑; 这些源码文档揭示了更深层次的操作细节和技术原理[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值