andriod R wifi 开启流程

8 篇文章 0 订阅

前言:

wifi chip 的开机初始化流程在这里我们就后面加上,本博客就暂时只有wifi的开启到wifi的连接成功.
虽然都是andriod R,但是还是有可能不同的基线版本代码还是有些许差别,所以我在设备下看了下基线和wifi的软件信息:

/system/bin # iwpriv wlan0 version                            
wlan0     version:Host SW:5.2.022.4Z, FW:1.0.1.0.31.0, HW:HW_VERSION=ffffffff., Board ver: 8 Ref design id: 0, Customer id: 0, Project id: 0, Board Data Rev: 1, REG DB: 0:0, BDF REG DB: 0:0
:/ # cat /vendor/firmware_mnt/verinfo/ver_info.txt
{
    "Image_Build_IDs": {
        "adsp": "ADSP.HT.5.3-00597-SM8250-1", 
        "aop": "AOP.HO.2.0-00187-SM8250_E-1", 
        "apps": "LA.UM.9.12.r1-09500-SMxx50.0-1", 
        "boot": "BOOT.XF.3.2-00310-SM8250-1", 
        "btfm": "BTFM.HST.2.0.0.c3-00403-QCACHROMZ-1", 
        "btfm_hsp": "BTFM.HSP.1.0.0.c1-00327-QCAHSPROMZ-1", 
        "cdsp": "CDSP.HT.2.3-00592-SM8250-1", 
        "common": "SM8250_SDX55.LA_TN.2-0_2-0.r1-00209-STD.PROD-3", 
        "cvp": "CVP.VPU.1.0-00050-PROD-1", 
        "glue": "GLUE.SM8250_LA_SDX55_TN.1.01-00351-NOOP_TEST-1", 
        "npu": "NPU.FW.2.0-00173-SM8250_NPU_PACK-1", 
        "qssi": "LA.QSSI.11.0.r1-08400-qssi.0-1", 
        "slpi": "SLPI.HY.3.0-00258-SM8250AZL-1", 
        "spss": "SPSS.A1.1.3.10-00020-SM8250AAAAANAZS-1", 
        "tz": "TZ.XF.5.8-00180-SM8250AAAAANAZT-1", 
        "tzapps": "TZ.APPS.2.0-00126-SM8250AAAAANAZT-1", 
        "video": "VIDEO.VPU.1.0-00089-PROD-1", 
        "wigig": "WIGIG.TLN.7.8-00008-WIGIGTLNZ-1", 
        "wlan_hsp": "WLAN.HSP.1.0.c1-00171-QCAHSPSWPL_V1_SILICONZ-1", 
        "wlan_hst": "WLAN.HST.1.0.1.r1-00900-QCAHSTSWPL_SILICONZ-1"
    }, 
    "Metabuild_Info": {
        "Meta_Build_ID": "SM8250_SDX55.LA_TN.2-0_2-0.r1-00209-STD.PROD-3", 
        "Product_Flavor": "asic", 
        "Time_Stamp": "2021-05-07 12:26:16"
    }, 
    "Version": "1.0"

流程:

1:
系统启动时,systemserver进程中会启动Wifiservice服务,启动该服务在SystemServer.java中:

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

private static final String WIFI_SERVICE_CLASS = "com.android.server.wifi.WifiService";
private static final String WIFI_SCANNING_SERVICE_CLASS ="com.android.server.wifi.scanner.WifiScanningService";
private static final String WIFI_RTT_SERVICE_CLASS ="com.android.server.wifi.rtt.RttService";
private static final String WIFI_AWARE_SERVICE_CLASS ="com.android.server.wifi.aware.WifiAwareService";
private static final String WIFI_P2P_SERVICE_CLASS ="com.android.server.wifi.p2p.WifiP2pService";

里面不仅包含WIFI_SERVICE_CLASS,还包含一些其他的服务也需要在这个时候启动.

if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
                // Wifi Service must be started first for wifi-related services.
                t.traceBegin("StartWifi");
                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();
            }

在启动Wifiservice之后,会将此服务加到ServiceManager中:

protected final void publishBinderService(String name, IBinder service,boolean allowIsolated, int dumpPriority) {
          ServiceManager.addService(name, service, allowIsolated, dumpPriority);}

2:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiService.java

Wifiservice启动时,创建WifiServiceImpl实例对象。它是整个系统WiFi服务的管理者,所有的用户端操作请求都将由它初步预处理,分发给不同的服务处理执行

public WifiService(Context contextBase) {
        super(contextBase);
        mWifiContext = new WifiContext(contextBase);
        WifiInjector injector = new WifiInjector(mWifiContext);
        WifiAsyncChannel channel =  new WifiAsyncChannel(TAG);
        mImpl = new WifiServiceImpl(mWifiContext, injector, channel);
    }

接着将WiFiserviceimpl服务加到servicemanager中:

@Override
    public void onStart() {
        Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
        publishBinderService(Context.WIFI_SERVICE, mImpl);
    }

调用到的还是这个函数:

protected final void publishBinderService(String name, IBinder service,boolean allowIsolated, int dumpPriority)
 {
ServiceManager.addService(name, service, allowIsolated, dumpPriority);
 }

3:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

省略一些代码:
是WifiServiceImpl初始化过程,构造该类函数。

public WifiServiceImpl(Context context, WifiInjector wifiInjector, AsyncChannel asyncChannel) {
          mClientModeImpl = mWifiInjector.getClientModeImpl();
          mActiveModeWarden = mWifiInjector.getActiveModeWarden();

WifiServiceImpl做了与WiFi服务管理的相关类的初始化.

  • ClientModeImpl 作为客户端的模式实现,作为客户端事件处理在这里完成,并所有的连接状态变化在这里初始化。
  • ActiveModeWarden 提供WiFi不同操作模式的配置实现。

到这里,系统启动完成,WifiService服务已正常运行

用户点击WiFi开关按钮打开WiFi,通过Android提供的WiFiManager的接口类,通过AIDL机制将事件传递至WifiSerivce管理服务,在WifiServiceImpl对象中对其处理:
             WifiManager --> WifiService --> WifiServiceImpl

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeWarden.java

public void wifiToggled() {
mWifiController.sendMessage(WifiController.CMD_WIFI_TOGGLED);
 	}

WifiService服务启动后,在WifiServiceImpl中,调用mActiveModeWarden.start()对其启动。
WifiController是ActiveModeWarden的内部类,继承StateMachine类,在ActiveModeWarden构造函数中对其进行初始化;

  private class WifiController extends StateMachine {private static final String TAG = "WifiController"; private boolean mWifiControllerReady = false;

WifiController状态机状态有三个如下:

  • defaultState
  • mDisabledState
  • mEnabledState

状态机启动时,根据WiFi开启状态进行状态机初始化。因WiFi是由关闭切换至打开,因此,状态机初始到“mDisabledState”状态。

@Override
        public void start() {
            boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
            boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
            boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();
            boolean isLocationModeActive = mWifiPermissionsUtil.isLocationModeEnabled();
            // Due to cyclic dependency of ActiveModeWarden and WifiApConfigStore, fetch
            // WifiConfigStore object later during WifiController.start().
            ......
            mWifiApConfigStore = mWifiInjector.getWifiApConfigStore();
            if (shouldEnableSta()) {
                startClientModeManager();
                setInitialState(mEnabledState);
            } else {
                setInitialState(mDisabledState);
            }
            mContext.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    // Location mode has been toggled...  trigger with the scan change
                    // update to make sure we are in the correct mode
                    scanAlwaysModeChanged();
                }
            }, new IntentFilter(LocationManager.MODE_CHANGED_ACTION));
            super.start();
        }          

WifiController接收到CMD_WIFI_TOGGLED消息,将在“mDisabledState”状态进行处理:

@Override
            public boolean processMessageFiltered(Message msg) {
                switch (msg.what) {
                    case CMD_WIFI_TOGGLED:
                    case CMD_SCAN_ALWAYS_MODE_CHANGED:
                        if (shouldEnableSta()) {
                            startClientModeManager();
                            transitionTo(mEnabledState);
                        }
                        break;
                    case CMD_SET_AP:
                        // note: CMD_SET_AP is handled/dropped in ECM mode - will not start here
                        if (msg.arg1 == 1) {
                            startSoftApModeManager((SoftApModeConfiguration) msg.obj);
                            transitionTo(mEnabledState);
                        }
                        break;
                    case CMD_RECOVERY_RESTART_WIFI:
                        log("Recovery triggered, already in disabled state");
                        // intentional fallthrough
                    case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
                        // wait mRecoveryDelayMillis for letting driver clean reset.
                        sendMessageDelayed(CMD_RECOVERY_RESTART_WIFI_CONTINUE,
                                readWifiRecoveryDelay());
                        break;
                    case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
                        if (shouldEnableSta()) {
                            startClientModeManager();
                            transitionTo(mEnabledState);
                        }
                        break;
                    default:
                        return NOT_HANDLED;
                }
                return HANDLED;
            }

在消息CMD_SCAN_ALWAYS_MODE_CHANGED中进行startClientModeManager:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeWarden.java

private boolean startClientModeManager() {
        Log.d(TAG, "Starting ClientModeManager");
        ClientListener listener = new ClientListener();
        ClientModeManager manager = mWifiInjector.makeClientModeManager(listener);
        ......
    }

进入makeClientModeManager:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiInjector.java

public ClientModeManager makeClientModeManager(ClientModeManager.Listener listener) {
        return new ClientModeManager(mContext, mWifiHandlerThread.getLooper(), mClock,
                mWifiNative, listener, mWifiMetrics, mSarManager, mWakeupController,
                mClientModeImpl);
    }

进入ClientModeManager:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeManager.java

   ClientModeManager(Context context, @NonNull Looper looper, Clock clock, WifiNative wifiNative,Listener listener, WifiMetrics wifiMetrics, SarManager sarManager,WakeupController wakeupController, ClientModeImpl clientModeImpl) {
        mContext = context;
        mClock = clock;
        mWifiNative = wifiNative;
        mModeListener = listener;
        mWifiMetrics = wifiMetrics;
        mSarManager = sarManager;
        mWakeupController = wakeupController;
        mClientModeImpl = clientModeImpl;
        mStateMachine = new ClientModeStateMachine(looper);
        mDeferStopHandler = new DeferStopHandler(TAG, looper);
        TAG = "WifiClientModeManager" + TAG_COUNT++;
    }

进入ClientModeStateMachine:

ClientModeStateMachine(Looper looper) {
            super(TAG, looper);
            // CHECKSTYLE:OFF IndentationCheck
            addState(mIdleState);
                addState(mStartedState, mIdleState);
                    addState(mScanOnlyModeState, mStartedState);
                    addState(mConnectModeState, mStartedState);
            // CHECKSTYLE:ON IndentationCheck

            setInitialState(mIdleState);
            start();
        }

跳转到start():发送ClientModeStateMachine.CMD_START

@Override
    public void start() {
        Log.d(TAG, "Starting with role ROLE_CLIENT_SCAN_ONLY");
        mRole = ROLE_CLIENT_SCAN_ONLY;
        mTargetRole = ROLE_CLIENT_SCAN_ONLY;
        mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
    }

ClientModeStateMachine类的状态机,并初始化到“mIdleState”状态和启动状态机。
有如下几个状态:

private final State mIdleState = new IdleState();
private final State mStartedState = new StartedState();
private final State mScanOnlyModeState = new ScanOnlyModeState();
private final State mConnectModeState = new ConnectModeState();

也就是:

  • IdleState
  • StartedState
  • ScanOnlyModeState
  • ConnectModeState

接下来在startClientModeManager()调用方法switchClientModeManagerRole(manager)切换客户端设置模式角色。

private boolean switchClientModeManagerRole(@NonNull ClientModeManager modeManager) {
        if (mSettingsStore.isWifiToggleEnabled()) {
            modeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY);
        } else if (checkScanOnlyModeAvailable()) {
            modeManager.setRole(ActiveModeManager.ROLE_CLIENT_SCAN_ONLY);
        } else {
            Log.e(TAG, "Something is wrong, no client mode toggles enabled");
            return false;
        }
        return true;
    }

进入ClientModeManager.java的setRole函数:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeManager.java

@Override
    public void setRole(@Role int role) {
        Preconditions.checkState(CLIENT_ROLES.contains(role));
        if (role == ROLE_CLIENT_SCAN_ONLY) {
            mTargetRole = role;
            // Switch client mode manager to scan only mode.
            mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_SCAN_ONLY_MODE);
        } else if (CLIENT_CONNECTIVITY_ROLES.contains(role)) {
            mTargetRole = role;
            // Switch client mode manager to connect mode.
            mStateMachine.sendMessage(ClientModeStateMachine.CMD_SWITCH_TO_CONNECT_MODE, role);
        }
    }

在setRole()方法中,将role设置的值保存在mTargetRole变量,并发送消息给ClientModeStateMachine状态机。 ActiveModeWarden类中WiFicontroller状态机在DisabledState状态处理完了“CMD_WIFI_TOGGLED”消息,状态机跳转至“EnabledState”。通过状态机机制可知,将会执行DisabledState.exit();执行EnabledState.enter()方法进入到EnabledState状态。WiFicontroller状态机在WiFi打开中将停留在该状态。

在ClientModeStateMachine初始状态为“IdleState”,接着将执行IdleState.enter()方法进入该状态,并开始处理CMD_START消息。

private class IdleState extends State {
            @Override
            public void enter() {
                Log.d(TAG, "entering IdleState");
                mClientInterfaceName = null;
                mIfaceIsUp = false;
            }
            @Override
            public void exit() {
                mModeListener.onStopped();
            }
            @Override
            public boolean processMessage(Message message) {
                switch (message.what) {
                    case CMD_START:
                        // Always start in scan mode first.
                        mClientInterfaceName =
                                mWifiNative.setupInterfaceForClientInScanMode(
                                mWifiNativeInterfaceCallback);
                        if (TextUtils.isEmpty(mClientInterfaceName)) {
                            Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
                            mModeListener.onStartFailure();
                            break;
                        }
                        transitionTo(mScanOnlyModeState);
                        break;
                    default:
                        Log.d(TAG, "received an invalid message: " + message);
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        }

在处理这个消息时,会调用到WifiNative.java的setupInterfaceForClientInScanMode:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

public String setupInterfaceForClientInScanMode(
            @NonNull InterfaceCallback interfaceCallback) {
        synchronized (mLock) {
            if (!startHal()) {
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            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);
            if (TextUtils.isEmpty(iface.name)) {
                Log.e(TAG, "Failed to create iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
                return null;
            }
            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);
            if (!registerNetworkObserver(iface.networkObserver)) {
                Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
                teardownInterface(iface.name);
                return null;
            }
            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));
            Log.i(TAG, "Successfully setup " + iface);

            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            return iface.name;
        }
    }

这个函数包含很多启动,一一进入梳理:

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

1:加载WiFi驱动的startHal():

/** Helper method invoked to start supplicant if there were no ifaces */
    private boolean startHal() {
        synchronized (mLock) {
            if (!mIfaceMgr.hasAnyIface()) {
                if (mWifiVendorHal.isVendorHalSupported()) {
                    if (!mWifiVendorHal.startVendorHal()) {
                        Log.e(TAG, "Failed to start vendor HAL");
                        return false;
                    }
                } else {
                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
                }
            }
            return true;
        }
    }

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java

在mWifiVendorHal.startVendorHal中:

 public boolean startVendorHal() {
        synchronized (sLock) {
            if (!mHalDeviceManager.start()) {
                mLog.err("Failed to start vendor HAL").flush();
                return false;
            }
            mLog.info("Vendor Hal started successfully").flush();
            return true;
        }
    }

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java

 public boolean start() {
         return 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 <= START_HAL_RETRY_TIMES) {
                        WifiStatus status = mWifi.start();
                        if (status.code == WifiStatusCode.SUCCESS) {
                            initIWifiChipDebugListeners();
                            managerStatusListenerDispatch();
                            if (triedCount != 0) {
                                Log.d(TAG, "start IWifi succeeded after trying "
                                         + triedCount + " times");
                            }
                            return true;
                        } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
                            // Should retry. Hal might still be stopping.
                            Log.e(TAG, "Cannot start IWifi: " + statusString(status)
                                    + ", Retrying...");
                            try {
                                Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
                            } catch (InterruptedException ignore) {
                                // no-op
                            }
                            triedCount++;
                        } else {
                            // Should not retry on other failures.
                            Log.e(TAG, "Cannot start IWifi: " + statusString(status));
                            return false;
                        }
                    }
                    Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
                    return false;
                }
            } catch (RemoteException e) {
                Log.e(TAG, "startWifi exception: " + e);
                return false;
            }
        }
    }

这里就到了HIDL,java层通过binder连接HIDL,下层通过HIDL连接service

通过binder调用,调用到wifi.cpp中的start().

android/hardware/interfaces/wifi/1.4/default/wifi.cpp

Return<void> 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) {
        // Create the chip instance once the HAL is started.
        chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
                             iface_util_, feature_flags_);
        run_state_ = RunState::STARTED;
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onStart().isOk()) {
                LOG(ERROR) << "Failed to invoke onStart callback";
            };
        }
        LOG(INFO) << "Wifi HAL started";
    } else {
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onFailure(wifi_status).isOk()) {
                LOG(ERROR) << "Failed to invoke onFailure callback";
            }
        }
        LOG(ERROR) << "Wifi HAL start failed";
        // Clear the event callback objects since the HAL start failed.
        event_cb_handler_.invalidate();
    }
    return wifi_status;
}
WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
    if (!mode_controller_->initialize()) {
        LOG(ERROR) << "Failed to initialize firmware mode controller";
        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    }
    legacy_hal::wifi_error legacy_status = legacy_hal_->initialize();
    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to initialize legacy HAL: "
                   << legacyErrorToString(legacy_status);
        return createWifiStatusFromLegacyError(legacy_status);
    }
    return createWifiStatus(WifiStatusCode::SUCCESS);
}

进入mode_controller_->initialize():

android/hardware/interfaces/wifi/1.4/default/wifi_mode_controller.cpp

bool WifiModeController::initialize() {
     if (!driver_tool_->LoadDriver()) {
         LOG(ERROR) << "Failed to load WiFi driver";
         return false;
     }
     return true;
  }

在wifi_load_driver()方法中,将调用系统接口加载WiFi驱动ko。

android/frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp

bool DriverTool::LoadDriver() {
   return ::wifi_load_driver() == 0;
     }

android/frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp

int wifi_load_driver() {
  #ifdef WIFI_DRIVER_MODULE_PATH
    if (is_wifi_driver_loaded()) {
      return 0;
    }
int wifi_load_driver() {
  #ifdef WIFI_DRIVER_MODULE_PATH
    if (is_wifi_driver_loaded()) {
      return 0;
    }
    if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) return -1;
  #endif

2:梳理iface.name = createStaIface(iface);

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

private String createStaIface(@NonNull Iface iface) {
         synchronized (mLock) {
              if (mWifiVendorHal.isVendorHalSupported()) {
                  return mWifiVendorHal.createStaIface(
                          new InterfaceDestoyedListenerInternal(iface.id));
              } else {
                  Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
                  return handleIfaceCreationWhenVendorHalNotSupported(iface);
              }
          }
      }

3:梳理:setupInterfaceForClientMode函数

android/frameworks/base/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java

该类的主要对WiFi80211nl管理接口的封装,接口在WiFicond守护进程中呈现给WiFi框架。该类提供的接口仅使用与WiFi框架,访问权限受selinux权限保护。setupInterfaceForClientMode()方法主要为Station模式设置接口。

public boolean setupInterfaceForClientMode(@NonNull String ifaceName,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) {
        Log.d(TAG, "Setting up interface for client mode");
        if (!retrieveWificondAndRegisterForDeath()) {
            return false;
        }
        if (scanCallback == null || pnoScanCallback == null || executor == null) {
            Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks");
            return false;
        }
        IClientInterface clientInterface = null;
        try {
            clientInterface = mWificond.createClientInterface(ifaceName);
        } catch (RemoteException e1) {
            Log.e(TAG, "Failed to get IClientInterface due to remote exception");
            return false;
        }
        if (clientInterface == null) {
            Log.e(TAG, "Could not get IClientInterface instance from wificond");
            return false;
        }
        Binder.allowBlocking(clientInterface.asBinder());
        // Refresh Handlers
        mClientInterfaces.put(ifaceName, clientInterface);
        try {
            IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl();
            if (wificondScanner == null) {
                Log.e(TAG, "Failed to get WificondScannerImpl");
                return false;
            }
            mWificondScanners.put(ifaceName, wificondScanner);
            Binder.allowBlocking(wificondScanner.asBinder());
            ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback);
            mScanEventHandlers.put(ifaceName,  scanEventHandler);
            wificondScanner.subscribeScanEvents(scanEventHandler);
            PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor,
                    pnoScanCallback);
            mPnoScanEventHandlers.put(ifaceName,  pnoScanEventHandler);
            wificondScanner.subscribePnoScanEvents(pnoScanEventHandler);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to refresh wificond scanner due to remote exception");
        }
        return true;
    }

4:ClientModeImpl状态机

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java

mRoamingState
                                  mConnectedState
                       mL2ConnectedState  mObtainingIpState
mDefaultState   mConnectModeState mDisconnectingState
                     mDisconnectedState

// CHECKSTYLE:OFF IndentationCheck
        addState(mDefaultState);
            addState(mConnectModeState, mDefaultState);
                addState(mL2ConnectedState, mConnectModeState);
                    addState(mObtainingIpState, mL2ConnectedState);
                    addState(mConnectedState, mL2ConnectedState);
                    addState(mRoamingState, mL2ConnectedState);
                addState(mDisconnectingState, mConnectModeState);
                addState(mDisconnectedState, mConnectModeState);
        // CHECKSTYLE:ON IndentationCheck

        setInitialState(mDefaultState);

        setLogRecSize(NUM_LOG_RECS_NORMAL);
        setLogOnlyTransitions(false);

5:在public void setRole(@Role int role)函数中还包含另外一个消息:

List<Integer> CLIENT_CONNECTIVITY_ROLES = Arrays.asList(
            ROLE_CLIENT_PRIMARY,
            ROLE_CLIENT_SECONDARY,
            ROLE_CLIENT_LOCAL_ONLY);

在IdleState状态中被转为ScanOnlyModeState状态:

transitionTo(mScanOnlyModeState);
流程 :IdleState.exit()->StartedState.enter()->StartedState.exit()->ScanOnlyModeState.enter()。
ClientModeStateMachine状态机已处于“ScanOnlyModeState”,接收到该消息后,并未在ScanOnlyModeStateprocessMessage方法中并未处理,而抛给父状态“StartedState”处理。在StartedState.processMessage()方法中对该消息进行了处理。

public boolean processMessage(Message message) {
                switch(message.what) {
                    case CMD_START:
                        // Already started, ignore this command.
                        break;
                    case CMD_SWITCH_TO_CONNECT_MODE:
                   
                        mRole = message.arg1; // could be any one of possible connect mode roles.
                        updateConnectModeState(WifiManager.WIFI_STATE_ENABLING,
                                WifiManager.WIFI_STATE_DISABLED);
                                
//切换设置clinent接口到连接模式。
                        if (!mWifiNative.switchClientInterfaceToConnectivityMode(
                                mClientInterfaceName)) {
                            updateConnectModeState(WifiManager.WIFI_STATE_UNKNOWN,
                                    WifiManager.WIFI_STATE_ENABLING);
                            updateConnectModeState(WifiManager.WIFI_STATE_DISABLED,
                                    WifiManager.WIFI_STATE_UNKNOWN);
                            mModeListener.onStartFailure();
                            break;
                        }
                        transitionTo(mConnectModeState);
                        break;
                    case CMD_SWITCH_TO_SCAN_ONLY_MODE:
                        updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
                                WifiManager.WIFI_STATE_ENABLED);
                        mDeferStopHandler.start(getWifiOffDeferringTimeMs());
                        break;
                    case CMD_SWITCH_TO_SCAN_ONLY_MODE_CONTINUE:
                        transitionTo(mScanOnlyModeState);
                        break;
                    case CMD_INTERFACE_DOWN:
                        Log.e(TAG, "Detected an interface down, reporting failure to "
                                + "SelfRecovery");
                        mClientModeImpl.failureDetected(SelfRecovery.REASON_STA_IFACE_DOWN);
                        // once interface down, nothing else to do...  stop the state machine
                        quitNow();
                        break;
                    case CMD_INTERFACE_STATUS_CHANGED:
                        boolean isUp = message.arg1 == 1;
                        onUpChanged(isUp);
                        break;
                    case CMD_INTERFACE_DESTROYED:
                        Log.e(TAG, "interface destroyed - client mode stopping");
                        mClientInterfaceName = null;
                        // once interface destroyed, nothing else to do...  stop the state machine
                        quitNow();
                        break;
                    default:
                        return NOT_HANDLED;
                }

updateConnectModeState: 更新WiFi打开状态,发送系统广播通知

private void updateConnectModeState(int newState, int currentState) {
          if (newState == WifiManager.WIFI_STATE_UNKNOWN) {
              // do not need to broadcast failure to system
              return;
          }
          if (mRole != ROLE_CLIENT_PRIMARY) {
              // do not raise public broadcast unless this is the primary client mode manager
              return;
          }
  
          mClientModeImpl.setWifiStateForApiCalls(newState);
  
          final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
          intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
          intent.putExtra(WifiManager.EXTRA_WIFI_STATE, newState);
          intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, currentState);
          mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
      }

switchClientInterfaceToConnectivityMode:切换设置clinent接口到连接模式。

public boolean switchClientInterfaceToConnectivityMode(@NonNull String ifaceName) {
        synchronized (mLock) {
        
//获取设置的接口
            final Iface iface = mIfaceMgr.getIface(ifaceName);
            if (iface == null) {
                Log.e(TAG, "Trying to switch to connectivity mode on an invalid iface="
                        + ifaceName);
                return false;
            }
            if (iface.type == Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY) {
                Log.e(TAG, "Already in connectivity mode on iface=" + ifaceName);
                return true;
            }
            //调用启动wpa_supplicant服务进程
            if (!startSupplicant()) {
                Log.e(TAG, "Failed to start supplicant");
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            } 
            //注册设置接口
            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
                return false;
            }
            iface.type = Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY;
            iface.featureSet = getSupportedFeatureSetInternal(iface.name);
            Log.i(TAG, "Successfully switched to connectivity mode on iface=" + iface);
            return true;
        }
    }

进入startSupplicant函数:
一个个函数进入篇幅太多,直接用这个流程表示一下:

  1. WifiNative.startSupplicant()
  2. WifiNative.startAndWaitForSupplicantConnection()
  3. SupplicantStaIfaceHal.startDaemon()
  4. SupplicantStaIfaceHal.startDaemon_V1_1()
  5. SupplicantStaIfaceHal.getSupplicantMockableV1_1()
  6. SupplicantStaIfaceHal.getSupplicantMockable()

现在我们直接进入SupplicantStaIfaceHal.getSupplicantMockable()

在getService的时候启动wpa_supplicant进程
,通过HIDL调用获取wpa_supplicant服务。ISupplicant.getService(supplicantName)调用到ISupplicant.java。

protected ISupplicant getSupplicantMockable() throws RemoteException, NoSuchElementException {
          synchronized (mLock) {
              ISupplicant iSupplicant = ISupplicant.getService();
              if (iSupplicant == null) {
                  throw new NoSuchElementException("Cannot get root service.");
              }
              return iSupplicant;
          }
      }

进入getService:运行时会将服务名称注册到hwservicemanager中

public static ISupplicant getService(String serviceName) throws android.os.RemoteException {
return ISupplicant.asInterface(android.os.HwBinder.getService("android.hardware.wifi.supplicant@1.0::ISupplicant", serviceName));
}

getService会触发启动wpa_supplicant进程:

  1. main.c
  2. wpa_supplicant.c->wpa_supplicant_init()
  3. notify.c->wpas_notify_supplicant_initialized()
  4. hidl.cpp->wpas_hidl_init()
  5. Hidl_manager.cpp->registerHidlService()

进入registerHidlService函数:

int HidlManager::registerHidlService(struct wpa_global *global)
  {
  	::android::status_t status;
  
  	// Create the main hidl service object and register it.
  	supplicant_object_ = new Supplicant(global);
  	if (global->params.hidl_service_name) {
  		wpa_printf(MSG_DEBUG, "hidl_register service name %s", global->params.hidl_service_name);
  		status = supplicant_object_->registerAsService(global->params.hidl_service_name);
  	} else {
  		wpa_printf(MSG_DEBUG, "hidl_register service name default");
  		status = supplicant_object_->registerAsService();
  	}
  
  	if (status != android::NO_ERROR) {
  		 return 1;
  	}
  	return 0;
  }
  • 将wpa_supplicant添加注册到hwservicemanager.
  • wpa_supplicant注册完成后,SupplicantStaIfaceHal类中将收到回调通知信息
private final IServiceNotification mServiceNotificationCallback =
              new IServiceNotification.Stub() {
          public void onRegistration(String fqName, String name, boolean preexisting) {
              synchronized (mLock) {
                  if (mVerboseLoggingEnabled) {
                      Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
                              + ", " + name + " preexisting=" + preexisting);
                  }
                  if (!initSupplicantService()) {
                      Log.e(TAG, "initalizing ISupplicant failed.");
                      supplicantServiceDiedHandler(mDeathRecipientCookie);
                  } else {
                      Log.i(TAG, "Completed initialization of ISupplicant.");
                  }
              }
          }
      };

wpa_supplicant进程服务已启动完成,函数执行switchClientInterfaceToConnectivityMode()结束。接着将调用SupplicantStaIfaceHal.setupIface()方法设置接口。设置成功将执行完WifiNative.switchClientInterfaceToConnectivityMode()方法并退出。

ClientModeStateMachine.CMD_SWITCH_TO_CONNECT_MODE消息是在startedstate进程中处理,switchClientInterfaceToConnectivityMode处理成功后直接切换到mConnectModeState.

private class ConnectModeState extends State {
            @Override
            public void enter() {
                Log.d(TAG, "entering ConnectModeState");
                mClientModeImpl.registerModeListener(mClientModeImplListener);
                mClientModeImpl.setOperationalMode(ClientModeImpl.CONNECT_MODE,
                        mClientInterfaceName);
            }
            @Override
            public boolean processMessage(Message message) {
                switch (message.what) {
                    case CMD_CONNECT_MODE_READY:
                        Log.d(TAG, "ConnectMode is ready");
                        mModeListener.onStarted();
                        updateConnectModeState(WifiManager.WIFI_STATE_ENABLED,
                                WifiManager.WIFI_STATE_ENABLING);
                        // Inform sar manager that wifi is Enabled
                        mSarManager.setClientWifiState(WifiManager.WIFI_STATE_ENABLED);
                        break;
                    case CMD_SWITCH_TO_CONNECT_MODE:
                        int newRole = message.arg1;
                        // Already in connect mode, only switching the connectivity roles.
                        if (newRole != mRole) {
                            mRole = newRole;
                            mModeListener.onStarted();
                        }
                        break;
                    case CMD_SWITCH_TO_SCAN_ONLY_MODE:
                        updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
                                WifiManager.WIFI_STATE_ENABLED);
                        return NOT_HANDLED; // Handled in StartedState.
                    case CMD_INTERFACE_DOWN:
                        updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
                                WifiManager.WIFI_STATE_UNKNOWN);
                        return NOT_HANDLED; // Handled in StartedState.
                    case CMD_INTERFACE_STATUS_CHANGED:
                        boolean isUp = message.arg1 == 1;
                        if (isUp == mIfaceIsUp) {
                            break;  // no change
                        }
                        if (!isUp) {
                            if (!mClientModeImpl.isConnectedMacRandomizationEnabled()) {
                                // Handle the error case where our underlying interface went down if
                                // we do not have mac randomization enabled (b/72459123).
                                // if the interface goes down we should exit and go back to idle
                                // state.
                                updateConnectModeState(WifiManager.WIFI_STATE_UNKNOWN,
                                        WifiManager.WIFI_STATE_ENABLED);
                            } else {
                                return HANDLED; // For MAC randomization, ignore...
                            }
                        }
                        return NOT_HANDLED; // Handled in StartedState.
                    case CMD_INTERFACE_DESTROYED:
                        updateConnectModeState(WifiManager.WIFI_STATE_DISABLING,
                                WifiManager.WIFI_STATE_ENABLED);
                        return NOT_HANDLED; // Handled in StartedState.
                    default:
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
  1. 设置客户端模式为连接模式:mClientModeImpl.setOperationalMode(ClientModeImpl.CONNECT_MODE,
    mClientInterfaceName);

  2. 发送系统广播,通知WiFi已打开: updateConnectModeState(WifiManager.WIFI_STATE_ENABLED,
    WifiManager.WIFI_STATE_ENABLING);

  3. 通知SAR管理着WiFi已打开: mSarManager.setClientWifiState(WifiManager.WIFI_STATE_ENABLED);

进入 mClientModeImpl.setOperationalMode:

public void setOperationalMode(int mode, String ifaceName) {
        if (mVerboseLoggingEnabled) {
            log("setting operational mode to " + String.valueOf(mode) + " for iface: " + ifaceName);
        }
        mModeChange = true;
        if (mode != CONNECT_MODE) {
            // we are disabling client mode...   need to exit connect mode now
            transitionTo(mDefaultState);
        } else {
            // do a quick sanity check on the iface name, make sure it isn't null
            if (ifaceName != null) {
                mInterfaceName = ifaceName;
                updateInterfaceCapabilities(ifaceName);
                transitionTo(mDisconnectedState);
                mWifiScoreReport.setInterfaceName(ifaceName);
            } else {
                Log.e(TAG, "supposed to enter connect mode, but iface is null -> DefaultState");
                transitionTo(mDefaultState);
            }
        }
        // use the CMD_SET_OPERATIONAL_MODE to force the transitions before other messages are
        // handled.
        sendMessageAtFrontOfQueue(CMD_SET_OPERATIONAL_MODE);
    }

最后转到了transitionTo(mDisconnectedState).
其中:

  • updateInterfaceCapabilities(ifaceName);//更新设置是否支持80211ax。

android/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ActiveModeWarden.java

private class ClientListener extends ModeCallback implements ActiveModeManager.Listener {
          @Override
          public void onStarted() {
              updateClientScanMode();
              updateBatteryStats();
          }
private void updateClientScanMode() {
          boolean scanEnabled = hasAnyClientModeManager();
          boolean scanningForHiddenNetworksEnabled;
          if (mContext.getResources().getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode)) {
              scanningForHiddenNetworksEnabled = hasAnyClientModeManager();
          } else {
              scanningForHiddenNetworksEnabled = hasAnyClientModeManagerInConnectivityRole();
          }
          mScanRequestProxy.enableScanning(scanEnabled, scanningForHiddenNetworksEnabled);
      }
private void enableScanningInternal(boolean enable) {
          if (!retrieveWifiScannerIfNecessary()) {
              Log.e(TAG, "Failed to retrieve wifiscanner");
              return;
          }
          mWifiScanner.setScanningEnabled(enable);
          sendScanAvailableBroadcast(mContext, enable);
          clearScanResults();
          Log.i(TAG, "Scanning is " + (enable ? "enabled" : "disabled"));
      }
public void setScanningEnabled(boolean enable) {
          validateChannel();
          mAsyncChannel.sendMessage(enable ? CMD_ENABLE : CMD_DISABLE);
      }

也就是:

  1. ActiveModeWarden.ClientListener
  2. ScanRequestProxy.enableScanning()
  3. ScanRequestProxy.enableScanningInternal()
  4. wifiScaner.setScanningEnabled()

学习少不了参考模仿,希望对大家有所帮助.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值