NetworkControllerImpl WifiSignalController MobileSignalController
在WifiSignalController的父类SignalController中可以看到
/**
* Gets the signal icon for SB based on current state of connected, enabled, and level.
*/
public int getCurrentIconId() {
if (mCurrentState.connected) {
return getIcons().mSbIcons[mCurrentState.inetCondition][mCurrentState.level];
} else if (mCurrentState.enabled) {
return getIcons().mSbDiscState;
} else {
return getIcons().mSbNullState;
}
}
1.1 NetworkControllerImpl 中收到广播
NetworkControllerImpl.java{
public void onReceive(Context context, Intent intent) {
if (CHATTY) {
Log.d(TAG, "onReceive: intent=" + intent);
}
final String action = intent.getAction();
//action meaning http://jcs.mobile-utopia.com/jcs/101974_connectivitymanager.html
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
//网络连接状态发生变化时
//网络连接不可用时
updateConnectivity();
.........
} else {
// No sub id, must be for the wifi.
mWifiSignalController.handleBroadcast(intent);
}
}
/**
* Update the Inet conditions and what network we are connected to.
*/
//更新 inet
private void updateConnectivity() {
mConnectedTransports.clear();
mValidatedTransports.clear();
//获取当前网络功能接口, 得到当前连接的网络类型以及是否有效 ------查看具体api
http://jcs.mobile-utopia.com/jcs/101974_connectivitymanager.html ConnectivityManager
for (NetworkCapabilities nc :mConnectivityManager.getDefaultNetworkCapabilitiesForUser(mCurrentUserId)) {
for (int transportType : nc.getTransportTypes()) {
//验证传输是否连接
mConnectedTransports.set(transportType);
//验证是否有网络,具体所有的数据都存在了里面验证的变量 mNetworkCapabilities
if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
mValidatedTransports.set(transportType);
}
}
}
...
//赋值网络是否有效
mInetCondition = !mValidatedTransports.isEmpty();
pushConnectivityToSignals();
}
/**
* Pushes the current connectivity state to all SignalControllers.
*/
private void pushConnectivityToSignals() {
// We want to update all the icons, all at once, for any condition change
for (int i = 0; i < mMobileSignalControllers.size(); i++) {
MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
mobileSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
}
mWifiSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
mEthernetSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
}
}
1.2 判断是否有有效网络的方法
是根据 mNetworkCapabilities 这个变量判断的,
public boolean hasCapability(int capability) {
if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
return false;
}
return ((mNetworkCapabilities & (1 << capability)) != 0);
}
1.3
全局搜索 addCapability () 的地方
mNetworkCapabilities 这个就有点类似 notification 里面的flag变量,会将所有的属性存储在 这个变量中。
ConnectivityService.java
ConnectivityService.java
private void updateCapabilities(
int oldScore, NetworkAgentInfo nai, NetworkCapabilities networkCapabilities) {
// Once a NetworkAgent is connected, complain if some immutable capabilities are removed.
if (nai.everConnected && !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
networkCapabilities)) {
// TODO: consider not complaining when a network agent degrade its capabilities if this
// does not cause any request (that is not a listen) currently matching that agent to
// stop being matched by the updated agent.
String diff = nai.networkCapabilities.describeImmutableDifferences(networkCapabilities);
if (!TextUtils.isEmpty(diff)) {
Slog.wtf(TAG, "BUG: " + nai + " lost immutable capabilities:" + diff);
}
}
// Don't modify caller's NetworkCapabilities.
networkCapabilities = new NetworkCapabilities(networkCapabilities);
if (nai.lastValidated) {
networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED);
} else {
networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED);
}
private boolean maybeHandleNetworkMonitorMessage(Message msg) {
switch (msg.what) {
default:
return false;
case NetworkMonitor.EVENT_NETWORK_TESTED: {
final NetworkAgentInfo nai;
synchronized (mNetworkForNetId) {
nai = mNetworkForNetId.get(msg.arg2);
}
if (nai != null) {
//网络测试验证的结果,是否有效网络
final boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
final boolean wasValidated = nai.lastValidated;
if (DBG) log(nai.name() + " validation " + (valid ? "passed" : "failed") +
(msg.obj == null ? "" : " with redirect to " + (String)msg.obj));
if (valid != nai.lastValidated) {
final int oldScore = nai.getCurrentScore();
nai.lastValidated = valid;
nai.everValidated |= valid;
//update Capabilities
updateCapabilities(oldScore, nai, nai.networkCapabilities);
// If score has changed, rebroadcast to NetworkFactories. b/17726566
if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
}
....
1.4 NetworkMonitor.java
// Being in the ValidatedState State indicates a Network is:
// - Successfully validated, or
// - Wanted "as is" by the user, or
// - Does not satisfy the default NetworkRequest and so validation has been skipped.
private class ValidatedState extends State {
@Override
public void enter() {
maybeLogEvaluationResult(
networkEventType(validationStage(), EvaluationResult.VALIDATED));
mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
NETWORK_TEST_RESULT_VALID, mNetId, null));
mValidations++;
}
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_NETWORK_CONNECTED:
transitionTo(mValidatedState);
return HANDLED;
default:
return NOT_HANDLED;
}
}
}
// Note: This call to isCaptivePortal() could take up to a minute. Resolving the
// server's IP addresses could hit the DNS timeout, and attempting connections
// to each of the server's several IP addresses (currently one IPv4 and one
// IPv6) could each take SOCKET_TIMEOUT_MS. During this time this StateMachine
// will be unresponsive. isCaptivePortal() could be executed on another Thread
// if this is found to cause problems.
//probeResult ,下面就是根据 probeResult 的结果判断
CaptivePortalProbeResult probeResult = isCaptivePortal();
if (probeResult.isSuccessful()) {
transitionTo(mValidatedState);
} else if (probeResult.isPortal()) {
//send EVENT_NETWORK_TESTED
mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
NETWORK_TEST_RESULT_INVALID, mNetId, probeResult.redirectUrl));
mLastPortalProbeResult = probeResult;
transitionTo(mCaptivePortalState);
} else {
final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
sendMessageDelayed(msg, mReevaluateDelayMs);
logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
mConnectivityServiceHandler.sendMessage(obtainMessage(
EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetId,
probeResult.redirectUrl));
protected CaptivePortalProbeResult isCaptivePortal() {
// mIsCaptivePortalCheckEnabled 是settings 数据库设置的值
// <setting type="global" name="captive_portal_mode" />
if (!mIsCaptivePortalCheckEnabled) {
validationLog("Validation disabled.");
return CaptivePortalProbeResult.SUCCESS;
}
URL pacUrl = null;
URL httpsUrl = mCaptivePortalHttpsUrl;
URL httpUrl = mCaptivePortalHttpUrl;
...
...
if (pacUrl != null) {
result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
} else if (mUseHttps) {
result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
} else {
result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
}
}
二. wifi 的 level WifiManager和WifiStatusTracker等用于追踪wifi信息,最终通过WifiStatusTracker handleBroadcast处理并且刷新信号
public void handleBroadcast(Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN);
enabled = state == WifiManager.WIFI_STATE_ENABLED;
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
final NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
connecting = networkInfo != null && !networkInfo.isConnected()
&& networkInfo.isConnectedOrConnecting();
connected = networkInfo != null && networkInfo.isConnected();
// If Connected grab the signal strength and ssid.
if (connected) {
// try getting it out of the intent first
WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
: mWifiManager.getConnectionInfo();
if (info != null) {
ssid = getSsid(info);
} else {
ssid = null;
}
} else if (!connected) {
ssid = null;
}
} else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
// ------------------------------level -------------------------------
// Default to -200 as its below WifiManager.MIN_RSSI.
rssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
level = WifiManager.calculateSignalLevel(rssi, 5);
}
}