android wifi upper module calls analysis

The company wifi module documentation

1. File Path

Files under these paths regardless of platform and large versions of Android

packages/../framework/src/com/../framework/wifi/LocalWifiSetting.java
packages/../framework/src/com/../framework/wifi/WifiAccessPoint.java
packages/../framework/src/com/../framework/wifi/WifiDevInfo.java

Depending android large versions, differentiated things into the framework / android / corresponding to the major version / wifi in

2. Code Details

packages /../ framework / src / com /../ framework / wifi / LocalWifiSetting.java upper layers through LocalWifiSetting.getInstance (mContext) Gets the singleton object constructor wifi register associated broadcast code is as follows:

public static LocalWifiSetting getInstance(Context context) {
    return (LocalWifiSetting) Context.getInstance(context).getSystemService(Context.WIFI_SETTING_SERVICE);
}

public LocalWifiSetting (Context context) {
    mWifiManager =(WifiManager)context.getSystemService(Context.WIFI_SERVICE);
    mContext=context;
    mScanner = new Scanner();
    mFilter = new IntentFilter();
    mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
    mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
    mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
    mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
    mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
    mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            handleEvent(context, intent);
        }   
    };  
    mContext.registerReceiver(mReceiver, mFilter);
} 

1, WIFI_STATE_CHANGED_ACTION: visual representation broadcast WIFI module hardware state change, there is seen, open WIFI, WIFI off; and in the actual process, WIFI from on to off or from off to on, to go through three states to open WIFI for example, the state were to go through: closed, open, it has been open and close the WIFI on the contrary, divided as follows:.. after you have opened and closed, turn off receiving this broadcast, you can from change the current state of INTENT removed WIFI hardware can be discriminated using the INT value; this is KEY: EXTRA_WIFI_STATE, possible to obtain values: 0, 1, 2, 3, 4; this acquisition mode except, of course, can also WIFIMANAGER Object GETWIFISTATE () Gets the value may be another value taken, showing a state before the WIFI module, corresponding KEY, it is from the INTENT:. EXTRA_PREVIOUS_WIFI_STATE;

2, WifiManager.SCAN_RESULTS_AVAILABLE_ACTION: scanning to a hot, and the hot spot reaches this trigger this broadcast availability status; At this time, you can remove the currently scanned by ScanResult wifiManager.getScanResult (); at the same time, you can be removed from the intent a boolean value; if this is true, on behalf of the scanning focus has been entirely successful; false, the representative of the scan is unsuccessful, ScanResult has not been updated since the last scan;

3, WifiManager.NETWORK_IDS_CHANGED_ACTION: after the network configuration, saving, adding, connected, disconnected, forgotten operation, are arranged and formed have WIFI hotspots impact, the shell, if root privileges, the operation may be performed before and after, respectively, Browse /data/misc/wifi/wpa_supplicant.conf should be a change in the nature of this case will receive this broadcast.

4, WifiManager.SUPPLICANT_STATE_CHANGED_ACTION: establish a hotspot is changing the relevant class is a symbol of change:. SupplicantState, you can at the time of receiving this broadcast, observe the entire connection process has been established hotspot, the connection may contain errors the error code.

5, WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION: official comment is to say, the broadcast configured network changes may add, modify, delete trigger network when the key is removed from EXTRA_MULTIPLE_NETWORKS_CHANGED intent, it is true, then the field. EXTRA_WIFI_CONFIGURATION taken out of the configuration is outdated and not up to date configured.

6, WifiManager.LINK_CONFIGURATION_CHANGED_ACTION: WIFI connection configuration change of the broadcast time, and the network connection function package LinkProperties NetworkCapabilities may change.

7, WifiManager.NETWORK_STATE_CHANGED_ACTION: WIFI connection state broadcasting changes occur can be obtained from NetworkInfo intent, in which case provides a new connection NetworkInfo state, if the connection is successful, you can get BSSID of the current network connection, and WifiInfo..

8, WifiManager.RSSI_CHANGED_ACTION: WIFI hotspots broadcast signal intensity changes occur can get the latest changes in signal strength of the current hot spots.

After receiving the broadcast will handleEvent:

private void handleEvent(Context context, Intent intent) {
    String action = intent.getAction();
    if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
        updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                WifiManager.WIFI_STATE_UNKNOWN));
    }else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
            updateWifiAccessPoints();
    } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||
            WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) ||
            WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
            updateWifiAccessPoints();
    } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
         SupplicantState state = (SupplicantState) intent.getParcelableExtra(
                    WifiManager.EXTRA_NEW_STATE);
            if (!mConnected.get() && SupplicantState.isHandshakeState(state)) {
                 updateConnectionState(WifiInfo.getDetailedStateOf(state));
             } else {
                 updateConnectionState(null);
             }

             int authState = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
             if ( authState == WifiManager.ERROR_AUTHENTICATING ) {
                 updateWifiAccessPoints();
             }
             DetailedState detailedState = WifiInfo.getDetailedStateOf(state);
             Log.i(TAG, "action: " + action + "state:" + detailedState + "authState:" + authState);
    } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
        NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
                WifiManager.EXTRA_NETWORK_INFO);
        mConnected.set(info.isConnected());
        updateWifiAccessPoints();
        updateConnectionState(info.getDetailedState());
    } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
        updateConnectionState(null);
    }
}

Our TV set, wifi state of the boot are open, if the boot is wifi internet access, they would receive receive WIFI_STATE_CHANGED_ACTION, CONFIGURED_NETWORKS_CHANGED_ACTION, NETWORK_STATE_CHANGED_ACTION, SUPPLICANT_STATE_CHANGED_ACTION, this state is a process from wifi to boot authentication, and then we were watching under our code processes.
WIFI_STATE_CHANGED_ACTION inside achieve updateWifiState

private void updateWifiState(int state) {
    dispatchWifiStateChanged(state);
    switch (state) {
        case WifiManager.WIFI_STATE_ENABLED:
            //mScanner.resume();
            return;
        case WifiManager.WIFI_STATE_ENABLING:
            break;
        case WifiManager.WIFI_STATE_DISABLED:
            break;
    }   

    mLastWifiInfo = null;
    mLastState = null;
    mScanner.pause();

}  

Here in fact I did not do anything, just clear the record number of global variables. Then CONFIGURED_NETWORKS_CHANGED_ACTION:

public void updateWifiAccessPoints() {
final int wifiState = mWifiManager.getWifiState();

switch (wifiState) {
    case WifiManager.WIFI_STATE_ENABLED:
        mWifiAccessPoints = constructWifiAccessPoints();
        break;
    case WifiManager.WIFI_STATE_ENABLING:
        break;
    case WifiManager.WIFI_STATE_DISABLING:
        break;
    case WifiManager.WIFI_STATE_DISABLED:
        break;
}
dispatchWifiStateChanged(wifiState);

/* 
 * mWifiAccessPoints is null when wifi is disabled,which will throw NullPointerException
 */
List<WifiAccessPoint> tmpList;
if (mWifiAccessPoints == null) {
    tmpList = new ArrayList<WifiAccessPoint>();
} else {
    tmpList = new ArrayList<WifiAccessPoint>(mWifiAccessPoints);
}
dispatchWifiAccessPointsChanged(tmpList);
}

By this time, wifiManger state is WIFI_STATE_ENABLED. (If you want to learn how to turn automatic connection has not been connected to wifi at your own wifi and read the source code before the last judgment, which is not AC) then we are more important constructWifiAccessPoints () function:

  private List<WifiAccessPoint> constructWifiAccessPoints() {
    Log.v(TAG, "constructWifiAccessPoints");
    ArrayList<WifiAccessPoint> accessPoints = new ArrayList<WifiAccessPoint>();
    /** Lookup table to more quickly update WifiAccessPoints by only considering objects with the
     * correct SSID.  Maps SSID -> List of WifiAccessPoints with the given SSID. 
     * 获取保存过的wifi信息
     * 
     */
    Multimap<String, WifiAccessPoint> apMap = new Multimap<String, WifiAccessPoint>();

    final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
    if (configs != null) {
        Log.v(TAG, "configs size = " + configs.size());
        for (WifiConfiguration config : configs) {
            WifiAccessPoint accessPoint = new WifiAccessPoint(mContext, config);
            if (mLastWifiInfo != null && mLastState != null)
                accessPoint.update(mLastWifiInfo, mLastState);
            accessPoints.add(accessPoint);
            apMap.put(accessPoint.ssid, accessPoint);
        }
    }

    //获取扫描到但未保存过的wifi
    final List<ScanResult> results = mWifiManager.getScanResults();
    if (results != null) {
        for (ScanResult result : results) {
            // Ignore hidden and ad-hoc networks.
            if (result.SSID == null || result.SSID.length() == 0 ||
                    result.capabilities.contains("[IBSS]")) {
                continue;
            }

            boolean found = false;
            for (WifiAccessPoint accessPoint : apMap.getAll(result.SSID)) {
                if (accessPoint.update(result))
                    found = true;
            }
            if (!found) {
                WifiAccessPoint accessPoint = new WifiAccessPoint(mContext, result);
                if (mLastWifiInfo != null && mLastState != null)
                    accessPoint.update(mLastWifiInfo, mLastState);
                accessPoints.add(accessPoint);
                apMap.put(accessPoint.ssid, accessPoint);
            }
        }
    }

    // Pre-sort accessPoints to speed preference insertion
    Collections.sort(accessPoints);
    return accessPoints;
}

This effect is mainly used to obtain the function WIfiAccessPoint, this class is mainly used to store information in wifi. constructWifiAccessPoints This function first before there is a link through mWifiManager.getConfiguredNetworks had wifi information, save it to ApMap, and then save the scanned wifi. Next is the NETWORK_STATE_CHANGED_ACTION.

 private void updateConnectionState(DetailedState state) {
    /* sticky broadcasts can call this when wifi is disabled */
    if (!mWifiManager.isWifiEnabled()) {
        mScanner.pause();
        return;
    }

    if (state == DetailedState.OBTAINING_IPADDR) {
        mScanner.pause();
    } else {
        //mScanner.resume();
    }

    mLastWifiInfo = mWifiManager.getConnectionInfo();
    Log.d(TAG, "updateConnectionState " + state);
    if (state != null) {
        mLastState = state;
    }

    if (mWifiAccessPoints != null) {
        for (WifiAccessPoint accessPoint : mWifiAccessPoints) {
            accessPoint.update(mLastWifiInfo, mLastState);
        }
    }
}

Here the main update the connection status of wifi, IDLE: idle SCANNING: Scanning CONNECTING: connection AUTHENTICATING: Authenticating ...
OBTAINING_IPADDR: Getting Ip address CONNECTED: Connected SUSPENDED: paused DISCONNECTING: Disconnecting .. .
the dISCONNECTED: disconnected fAILED: failed bLOCKED: blocked VERIFYING_POOR_LINK: temporarily closed (poor network conditions)
CAPTIVE_PORTAL_CHECK: to determine whether you need to login a second time, there are more than several states. When we receive SUPPLICANT_STATE_CHANGED_ACTION broadcast, processing handleEvent as follows:

         SupplicantState state = (SupplicantState) intent.getParcelableExtra(
                    WifiManager.EXTRA_NEW_STATE);
            if (!mConnected.get() && SupplicantState.isHandshakeState(state)) {
                 updateConnectionState(WifiInfo.getDetailedStateOf(state));
             } else {
                 // During a connect, we may have the supplicant
                 // state change affect the detailed network state.
                 // Make sure a lost connection is updated as well.
                 updateConnectionState(null);
             }

             int authState = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1);
             if ( authState == WifiManager.ERROR_AUTHENTICATING ) {
                 updateWifiAccessPoints();
             }

             DetailedState detailedState = WifiInfo.getDetailedStateOf(state);
             Log.i(TAG, "action: " + action + "state:" + detailedState + "authState:" + authState);

Here mainly deal with wifi dealt with after the authentication fails. This part is updateWifiAccessPoints (), the following look packages /../ framework / src / com /../ framework / wifi / WifiAccessPoint.java, where mainly for recording details of each wifi, each constructed time status updates, it goes to reconstruct each WifiAccessPoint, then fresh.
WifiAccessPoint (the Context context, config WifiConfiguration) {
loadConfig (config);
Refresh ();
}

WifiAccessPoint(Context context, ScanResult result) {                                     
    loadResult(result);                                                                   
    refresh();                                                                            
} 

In refresh the main reason is to update the error:

private void refresh() {
    if (getState() != null) { // This is the active connection
        mDisableReason = -1;
    } else if (getRssiLevel() == Integer.MAX_VALUE) { // Wifi out of range
        mDisableReason = -1;
    } else if (mConfig != null && mConfig.status == WifiConfiguration.Status.DISABLED) {
        switch (mConfig.disableReason) {
            case WifiConfiguration.DISABLED_AUTH_FAILURE:
                mDisableReason = WifiConfiguration.DISABLED_AUTH_FAILURE;
                break;
            case WifiConfiguration.DISABLED_DHCP_FAILURE:
            case WifiConfiguration.DISABLED_DNS_FAILURE:
            case WifiConfiguration.DISABLED_UNKNOWN_REASON:
                mDisableReason = mConfig.disableReason;
                break;
        }
    } else { // In range, not disabled.
        mDisableReason = -1;

    }
}

Certified connected directly update the wifi state saved on the line. That is how the state change notification upper wifi it? This is mainly /../ in packages framework / src / com /../ framework / wifi / LocalWifiSetting.java in here to write the interfaces, the upper layer by implementing this interface to handle events. We trigger callback where needed.

public interface WifiStateChangeListerner {
    void onWifiAccessPointsChanage(List<WifiAccessPoint> accessPoints);

    void onWifiStateChanage(int state);
}

private final Collection<WifiStateChangeListerner> mCallbacks = new ArrayList<WifiStateChangeListerner>();

//上层调用这里注册回调
public void registerCallback(WifiStateChangeListerner callback) {
    synchronized (mCallbacks) {
        mCallbacks.add(callback);
    }
}

public void unregisterCallback(WifiStateChangeListerner callback) {
    synchronized (mCallbacks) {
        mCallbacks.remove(callback);
    }
}

//当wifi的状态发生改变的时候适配层触发此函数,回调上层实现
private void dispatchWifiStateChanged(int state) {
    synchronized (mCallbacks) {
        for (WifiStateChangeListerner callback : mCallbacks) {
            callback.onWifiStateChanage(state);
        }
    }
}

//当Wifi信息出现变化的时候适配层触发此函数,回调上层实现
private void dispatchWifiAccessPointsChanged(List<WifiAccessPoint> accessPoints) {
    synchronized (mCallbacks) {
        for (WifiStateChangeListerner callback : mCallbacks) {
            callback.onWifiAccessPointsChanage(accessPoints);
        }
    }
}

Here the comparison logic to wifi adaptation layer is almost complete, a basic function name to see other functions can understand the meaning of substantially: substantially /../ framework / src / com /../ framework / wifi in packages / LocalWifiSetting.java the find, connect, access to wifi information, delete saved wifi, etc.

### ethernet module document
then introduce Ethernet process. The main file path:

packages/../framework/src/com/../framework/ethernet/LocalEthCallback.java
packages/../framework/src/com/../framework/ethernet/LocalEthernetDevInfo.java
packages/../framework/src/com/../framework/ethernet/LocalEthManager.java

Like wifi, the main class is LocalEthManager, but the inside is basically abstract methods and classes specific implementation is as follows: 4.4 here because it was time to put Ethernet at mstar, that time will be found with the 5.0 version of the big change change, to achieve this part is placed packages /../ framework / android / corresponding major version / ehernet / under, can be analyzed in accordance with the corresponding large version, we first android4.4 to analyze.
It can be implemented in two ways:
./framework/hardware/mstar/tv1/src/ethernet/MstarLocalEthManager.java
./framework/hardware/mtk/tv1/src/ethernet/MtkLocalEthManager.java
./framework/hardware/softwinner/ tv1 / src / ethernet / SoftwinnerLocalEthManager.java
./framework/hardware/hisilicon/tv1/src/ethernet/HisiLocalEthManager.java
./framework/hardware/amlogic/tv1/src/ethernet/AmlogicLocalEthManager.java
./framework/android/lollipop /src/ethernet/LocalEthManager.java
these are the concrete realization LocalEthManager.java, compiled when the big android version will take precedence, if the android version is not at large exist, depending on the configuration, take the appropriate board or chip makers lower.

类似与wifi的流程有点类似,上层通过LocalWifiSetting.getInstance(mContext)获取单例对象:
public LocalEthManager(Context context) {
if (DEBUG)
Log.d(TAG, "LocalEthManager construct");
mEthernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE);
mConnectivityManager = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
IntentFilter intentfilter = new IntentFilter();
intentfilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(mBroadcastReceiver, intentfilter);
}

In fact, ethernet implementation simpler, mainly listening CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE", receiving the broadcast, trigger callback connection status, to use the upper
Private Final BroadcastReceiver mBroadcastReceiver = new new BroadcastReceiver () {
public void onReceive (Context context, the Intent Intent) {
// the TODO Auto-Generated Method Stub
int type = intent.getIntExtra (ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_NONE);
IF (type == ConnectivityManager.TYPE_ETHERNET) {
the NetworkInfo NetworkInfo = mConnectivityManager.getNetworkInfo (ConnectivityManager.TYPE_ETHERNET );
IF (the DEBUG)
Log.d (the TAG, "Change Action State the Eth");
! IF (NetworkInfo = null && networkInfo.isConnected ()) {
Log.d (the TAG, "LocalEthManager.EVENT_ETH_CONNECTED");
dispatchEthEvent(LocalEthManager.EVENT_ETH_CONNECTED);
} else {
Log.d(TAG,"LocalEthManager.EVENT_ETH_DISCONNECTED");
dispatchEthEvent(LocalEthManager.EVENT_ETH_DISCONNECTED);
}
}
}
};

Other functions are ethernet get relevant information to the upper layer.
isEthernetAvailable () --------------- supports Ethernet
getSavedEthConfig () --------------- get hold of Ethernet, IP and static points non-static, construct the corresponding LocalEthernetDevInfo
updateEthDevInfo () ---------------- Ethernet updated information (should not use the upper layer)
getDhcpInfo ()

Guess you like

Origin blog.51cto.com/6433051/2402761