Android Wifi State保存

    在Android系统中,在关开机之后发现Wifi仍然保持着关机之前的状态,就很好奇Wifi State是保存在那里的。如果是保存在Settings应用中的话,则必须要打开Settings才能触发保存的状态。但是Wifi是开机进入home界面之后就触发了。所以肯定在App层下面,framework层。
    要追查追查Wifi State,想到了每次打开关闭wifi需要调用的WifiManger.setWifiEnabled(),下面我们将一步一步追查。
    在Settings app中,在那里去触发wifi自动打开的呢,要看WiFiEnabler.java,它主要控制wifi开关控件switch。setSwitch函数是初始化WifiEnabler时调用的去打开的。onCheckedChanged函数是switch控件状态改变时,会调用的灰调函数。

    public void setSwitch(Switch switch_) {
        if (mSwitch == switch_) return;
        mSwitch.setOnCheckedChangeListener(null);
        mSwitch = switch_;
        mSwitch.setOnCheckedChangeListener(this);

        final int wifiState = mWifiManager.getWifiState();
        boolean isEnabled = wifiState == WifiManager.WIFI_STATE_ENABLED;
        boolean isDisabled = wifiState == WifiManager.WIFI_STATE_DISABLED;
        mSwitch.setChecked(isEnabled);
        mSwitch.setEnabled(isEnabled || isDisabled);
    }

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        
        if (mWifiManager.setWifiEnabled(isChecked)) {
            // Intent has been taken into account, disable until new state is active
            mSwitch.setEnabled(false);
        } else {
            // Error
            Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
        }
    }

    可以看到setSwitch函数初始化switch时,是通过WifiManger.getWifiState()去获取的。这说明Wifi State保存在更底层。在onCheckedChanged函数中,每当wifi状态改变时,通过WiFiManager.setWifiEnabled函数去向framework设置。设置时,Wifi State也要随着更改并保存。
    接下来我们就看下WifiManager.setWifiEnabled函数。mService是IWifiManager的new出的对象。通过aidl调用到WifiService.java
 public boolean setWifiEnabled(boolean enabled) {
        try {
            mService.setWifiEnabled(enabled);
        } catch (RemoteException e) {
            return false;
        }
    }

    我们继续看WiFiService.java,在setWifiEnabled中调用WifiStateMachine.setWifiEnabled,调用wifi状态机去loaddriver、初始化supplicant等打开wifi的操作。注意在下面有一句handleWifiToggled(enable),这个函数继续向下追有persistwifiState函数。这个函数有一句Settings.Global.putInt,这里就是保存Wifi State的地方。Settings.Global.putInt类似于Android中SharedPreference。

 public synchronized boolean setWifiEnabled(boolean enable) {
       
        if (enable) {
            reportStartWorkSource();
        }
        mWifiStateMachine.setWifiEnabled(enable);

        long ident = Binder.clearCallingIdentity();
        try {
            handleWifiToggled(enable);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        
        return true;
    }

    private void handleWifiToggled(boolean wifiEnabled) {
        boolean airplaneEnabled = mAirplaneModeOn.get() && isAirplaneToggleable();
        if (wifiEnabled) {
            if (airplaneEnabled) {
                persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE);
            } else {
                persistWifiState(WIFI_ENABLED);
            }
        } else {
            // When wifi state is disabled, we do not care
            // if airplane mode is on or not. The scenario of
            // wifi being disabled due to airplane mode being turned on
            // is handled handleAirplaneModeToggled()
            persistWifiState(WIFI_DISABLED);
        }
    }

    private void persistWifiState(int state) {
        final ContentResolver cr = mContext.getContentResolver();
        mPersistWifiState.set(state);
        Settings.Global.putInt(cr, Settings.Global.WIFI_ON, state);
    }

    到这里我们已经知道保存Wifi State的地方了,但是开机时怎么去触发的呢。那我们继续在wifiService.java文件中找,看看什么时候去读取mPersistWiFiSate的状态的。看出有getPersistedWifiState返回Wifi State,在checkAndStartWifi中有调用。就说明Wifi State最初的状态是有checkAndStartWifi获取,并进行了Wifi状态的初始化。

  private int getPersistedWifiState() {
        final ContentResolver cr = mContext.getContentResolver();
        try {
            return Settings.Global.getInt(cr, Settings.Global.WIFI_ON);
        } catch (Settings.SettingNotFoundException e) {
            Settings.Global.putInt(cr, Settings.Global.WIFI_ON, WIFI_DISABLED);
            return WIFI_DISABLED;
        }
    }

    public void checkAndStartWifi() {
        mAirplaneModeOn.set(isAirplaneModeOn());
        mPersistWifiState.set(getPersistedWifiState());
        /* Start if Wi-Fi should be enabled or the saved state indicates Wi-Fi was on */
        boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();
        Slog.i(TAG, "WifiService starting up with Wi-Fi " +(wifiEnabled ? "enabled" : "disabled"));

        // If we are already disabled (could be due to airplane mode), avoid changing persist
        // state here
        if (wifiEnabled) setWifiEnabled(wifiEnabled);

        mWifiWatchdogStateMachine = WifiWatchdogStateMachine.makeWifiWatchdogStateMachine(mContext);
    }

    为什么开机时,会调用checkAndStartWifi呢。这是因为WiFiService为system service,在开机时会被添加启动起来。我们来看SystemServer.java,调用checkAndStartWifi函数对Wifi进行初始化。
		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);
			wifi.checkAndStartWifi();
			wifiP2p.connectivityServiceReady();
		} catch (Throwable e) {
			reportWtf("starting Connectivity Service", e);
		}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值