[Network]Android N 新wifi connect&auto connect流程分析

本文详细分析了Android N系统中针对Wi-Fi连接的改进,包括WifiConnectivityManager如何管理扫描和连接操作。重点讲解了WifiManager.connect()方法的处理流程,以及在连接指定SSID时如何避免与自动连接逻辑冲突。此外,还介绍了自动连接(Auto connect)功能的重构,特别是如何在亮屏状态下进行周期性扫描,并通过算法选择最佳网络进行连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WifiConnectivityManager

前面提到的新 Android N scan机制 ,现在再看一个新的东西,WifiConnectivityManager,之前android connect一个wifi和做scan的操作都是放在wifistatemachine中的,整个看起来很杂乱。现在google在android N中做了个新的东西,WifiConnectivityManager,通过这个东西来管理scan和connect。这里我从wifi connect一个ssid的流程来看这个WifiConnectivityManager.

WifiManager.connect()

这个API没有发生变动。

    public void connect(WifiConfiguration config, ActionListener listener) {
        if (config == null) throw new IllegalArgumentException("config cannot be null");
        // Use INVALID_NETWORK_ID for arg1 when passing a config object
        // arg1 is used to pass network id when the network already exists
        getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
                putListener(listener), config);
    }

在WifiserviceImpl.java中会收到这个CMD,跟着做相应的处理

/*
WifiServiceImpl.java (frameworks\opt\net\wifi\service\java\com\android\server\wifi)
*/
     */
    private class ClientHandler extends Handler {
   

        ClientHandler(Looper looper) {
            super(looper);
        }
         @Override
        public void handleMessage(Message msg) { 
        ............      
                case WifiManager.CONNECT_NETWORK:
                case WifiManager.SAVE_NETWORK: {
                    WifiConfiguration config = (WifiConfiguration) msg.obj;
                    int networkId = msg.arg1;
                    if (msg.what == WifiManager.SAVE_NETWORK) {
                        Slog.d("WiFiServiceImpl ", "SAVE"
                                + " nid=" + Integer.toString(networkId)
                                + " uid=" + msg.sendingUid
                                + " name="
                                + mContext.getPackageManager().getNameForUid(msg.sendingUid));
                    }
                    if (msg.what == WifiManager.CONNECT_NETWORK) {
                        Slog.d("WiFiServiceImpl ", "CONNECT "
                                + " nid=" + Integer.toString(networkId)
                                + " uid=" + msg.sendingUid
                                + " name="
                                + mContext.getPackageManager().getNameForUid(msg.sendingUid));
                    }

                    if (config != null && isValid(config)) {
                        if (DBG) Slog.d(TAG, "Connect with config" + config);
                        //直接给WifiStatemachine把这个CMD送过去
                        mWifiStateMachine.sendMessage(Message.obtain(msg));
                    } else if (config == null
                            && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
                        if (DBG) Slog.d(TAG, "Connect with networkId" + networkId);
                        mWifiStateMachine.sendMessage(Message.obtain(msg));
                    } else {
                        Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
                        if (msg.what == WifiManager.CONNECT_NETWORK) {
                            replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED,
                                    WifiManager.INVALID_ARGS);
                        } else {
                            replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED,
                                    WifiManager.INVALID_ARGS);
                        }
                    }
                    break;
                }

.........................

看下wifistatemachinemachine,一般都是在ConnectModeState中会处理这个:

/*
WifiStateMachine.java (frameworks\opt\net\wifi\service\java\com\android\server\wifi)    
*/

class ConnectModeState extends State {
   
        ..........
       case WifiManager.CONNECT_NETWORK:
       .............................
                    /* Tell network selection the user did try to connect to that network if from
                    settings */
                    boolean persist =
                        mWifiConfigManager.checkConfigOverridePermission(message.sendingUid);


//设置mLastSelectedConfiguration变量,表示最近一次用户选择连接的热点                    mWifiConfigManager.setAndEnableLastSelectedConfiguration(netId);
                    if (mWifiConnectivityManager != null) {
                        //通过WifiConnectivityManager去连接
                        mWifiConnectivityManager.connectToUserSelectNetwork(netId, persist);
                    }


                //Start a new ConnectionEvent due to connect_network, this is always user
                    //selected
                    mWifiMetrics.startConnectionEvent(config, mTargetRoamBSSID,
                            WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED);
                    if (mWifiConfigManager.selectNetwork(config, /* updatePriorities = */ true,
                            message.sendingUid) && mWifiNative.reconnect()) {
                        lastConnectAttemptTimestamp = System.currentTimeMillis();
                        targetWificonfiguratio
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值