天天看点

Wifi模块—源码分析Wifi初始化(Android P)

机器启动的时候,主要做了3件事情:

1 添加注册ConnectivityService连接服务,它跟所有手机的无线通信都有联系,包括wifi,蓝牙,2g网络,3g网络等。

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

private void startOtherServices() {
    ...
    try {
        connectivity = new ConnectivityService(
                context, networkManagement, networkStats, networkPolicy);
        ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity,
                /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
        networkStats.bindConnectivityManager(connectivity);
        networkPolicy.bindConnectivityManager(connectivity);
    } catch (Throwable e) {
        reportWtf("starting Connectivity Service", e);
    }
    ...
}
           

2 管理开机wifi开启与否。

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

@Override
public void onBootPhase(int phase) {
    if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
        mImpl.checkAndStartWifi();
    }
}
           

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

/**
* Check if we are ready to start wifi.
*
* First check if we will be restarting system services to decrypt the device. If the device is
* not encrypted, check if Wi-Fi needs to be enabled and start if needed
*
* This function is used only at boot time.
*/
public void checkAndStartWifi() {
    // First check if we will end up restarting WifiService
    if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
        Log.d(TAG, "Device still encrypted. Need to restart SystemServer.  Do not start wifi.");
        return;
    }

    // Check if wi-fi needs to be enabled
    boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
    Slog.i(TAG, "WifiService starting up with Wi-Fi " +
                (wifiEnabled ? "enabled" : "disabled"));

    registerForScanModeChange();
    mContext.registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (mSettingsStore.handleAirplaneModeToggled()) {
                        mWifiController.sendMessage(CMD_AIRPLANE_TOGGLED);
                    }
                    if (mSettingsStore.isAirplaneModeOn()) {
                        Log.d(TAG, "resetting country code because Airplane mode is ON");
                        mCountryCode.airplaneModeEnabled();
                    }
                }
            },
            new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));

    mContext.registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    String state = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
                    if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(state)) {
                        Log.d(TAG, "resetting networks because SIM was removed");
                        mWifiStateMachine.resetSimAuthNetworks(false);
                    } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(state)) {
                        Log.d(TAG, "resetting networks because SIM was loaded");
                        mWifiStateMachine.resetSimAuthNetworks(true);
                    }
                }
            },
            new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED));

    mContext.registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    final int currState = intent.getIntExtra(EXTRA_WIFI_AP_STATE,
                                                                    WIFI_AP_STATE_DISABLED);
                    final int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_AP_STATE,
                                                                 WIFI_AP_STATE_DISABLED);
                    final int errorCode = intent.getIntExtra(EXTRA_WIFI_AP_FAILURE_REASON,
                                                                 HOTSPOT_NO_ERROR);
                    final String ifaceName =
                                intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
                    final int mode = intent.getIntExtra(EXTRA_WIFI_AP_MODE,
                                                            WifiManager.IFACE_IP_MODE_UNSPECIFIED);
                    handleWifiApStateChange(currState, prevState, errorCode, ifaceName, mode);
                }
            },
            new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION));

    // Adding optimizations of only receiving broadcasts when wifi is enabled
    // can result in race conditions when apps toggle wifi in the background
    // without active user involvement. Always receive broadcasts.
    registerForBroadcasts();
    mInIdleMode = mPowerManager.isDeviceIdleMode();

    if (!mWifiStateMachine.syncInitialize(mWifiStateMachineChannel)) {
        Log.wtf(TAG, "Failed to initialize WifiStateMachine");
    }
    mWifiController.start();

    // If we are already disabled (could be due to airplane mode), avoid changing persist
    // state here
    if (wifiEnabled) {
        try {
            setWifiEnabled(mContext.getPackageName(), wifiEnabled);
        } catch (RemoteException e) {
            /* ignore - local call */
        }
    }
}
           

3 添加注册wifi的核心服务wifiservice。

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

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

WifiService继承SystemService。

frameworks/base/services/core/java/com/android/server/SystemService.java

/**
* Publish the service so it is accessible to other services and apps.
*
* @param name the name of the new service
* @param service the service object
*/
protected final void publishBinderService(String name, IBinder service) {
    publishBinderService(name, service, false);
}

/**
* Publish the service so it is accessible to other services and apps.
*
* @param name the name of the new service
* @param service the service object
* @param allowIsolated set to true to allow isolated sandboxed processes
* to access this service
*/
protected final void publishBinderService(String name, IBinder service,
        boolean allowIsolated) {
    publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
}

/**
* Publish the service so it is accessible to other services and apps.
*
* @param name the name of the new service
* @param service the service object
* @param allowIsolated set to true to allow isolated sandboxed processes
* to access this service
* @param dumpPriority supported dump priority levels as a bitmask
*/
protected final void publishBinderService(String name, IBinder service,
        boolean allowIsolated, int dumpPriority) {
    ServiceManager.addService(name, service, allowIsolated, dumpPriority);
}