アンドロイドのwifi上部モジュールコール分析

同社の無線LANモジュールのドキュメント

1.ファイルパス

プラットフォームに関係なく、これらのパスの下のファイルとAndroidの大きなバージョン

パッケージ/../フレームワーク/ SRC / COM /../フレームワーク/ WIFI / LocalWifiSetting.javaの
パッケージ/../フレームワーク/ SRC / COM /../フレームワーク/ WIFI / WifiAccessPoint.javaの
パッケージ/../フレームワーク/ SRC /com/../framework/wifi/WifiDevInfo.java

/フレームワーク/アンドロイドにアンドロイド大きなバージョン、差別の事を依存してメジャーバージョン/無線LANに対応

2.コードの詳細

パッケージ/../フレームワーク/ SRC / COM /../フレームワーク/ WIFI / LocalWifiSetting.java上層LocalWifiSetting.getInstance(mContext)を介して、シングルトンオブジェクトコンストラクタWIFIレジスタ関連する放送コードを取得し、以下の通りであります:

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:視覚的表現ブロードキャストWIFIモジュールのハードウェア状態変化、見られ、オープンWIFIがあり、WIFIオフ;および実際のプロセスにおいて、オンからオフに、またはオフからオンにWIFI、三つの状態を通過します状態が通過した例えばWIFIを開くには、:閉じ、開いている、それがオープンされていると逆にWIFIを閉じ、次のように分かれています:..あなたが開閉した後、この放送を受信オフに、あなたがすることができますから、 EXTRA_WIFI_STATE、可能な値を得るために:これはキーである。INTENT除去WIFIハードウェアの現在の状態がINT値を用いて判別することができる変更0、1、2、3、4、この取得モード以外は、もちろん、WIFIMANAGER缶オブジェクトGETWIFISTATEは()キーに対応する、値はWiFiモジュール前の状態を示す、採取された特定の値であってもよい取得し、それはINTENT :. EXTRA_PREVIOUS_WIFI_STATEからです。

2、WifiManager.SCAN_RESULTS_AVAILABLE_ACTIONは:ホット、ホットスポットへのスキャンは、このトリガーにこの放送の可用性ステータスに到達し、この時点で、あなたは現在ScanResult wifiManager.getScanResult()でスキャンし削除することができ、同時に、あなたが意図から削除することができますブール値;これがtrueの場合は、走査焦点に代わって完全に成功しているし、false、スキャンの代表が失敗し、ScanResultは最後のスキャン以降に更新されていません。

図3に示すように、WifiManager.NETWORK_IDS_CHANGED_ACTION:ネットワーク構成後、保存、追加、接続、切断、忘れられ動作は、配置及び形成されたWiFiホットスポットの影響を有する、シェル、ルート権限場合、動作は、それぞれ、前および後に行ってもよいですこの放送を受信します/data/misc/wifi/wpa_supplicant.confは、この事件の性質が変化する必要があります参照します。

4、WifiManager.SUPPLICANT_STATE_CHANGED_ACTION:ホットスポットを確立SupplicantState :.変更の記号は、あなたがこのブロードキャストを受信した時に、関連するクラスをすることができますされ変更され、接続がエラーを含むことができ、全体の接続処理がホットスポットに確立された観察エラーコード。

5、WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION:公式のコメントは、放送設定されたネットワークの変更は、修正、追加キーはEXTRA_MULTIPLE_NETWORKS_CHANGED意図から削除されたときにトリガネットワークを削除しても良いと言うことです、それは本当、そのフィールドです。コンフィギュレーションから取り出したEXTRA_WIFI_CONFIGURATIONは時代遅れとないように最新のものです。

6、WifiManager.LINK_CONFIGURATION_CHANGED_ACTION:放送時間のWIFI接続構成の変更、およびLinkPropertiesのNetworkCapabilitiesが変更される可能性があり、ネットワーク接続機能パッケージ。

7、WifiManager.NETWORK_STATE_CHANGED_ACTION:接続が成功した場合はWIFI接続状態放送の変更は状態NetworkInfo新しい接続を提供し、その場合には、意図NetworkInfoから入手することができます発生し、あなたは現在のネットワーク接続のBSSID、およびWifiInfoを得ることができます。..

8、WifiManager.RSSI_CHANGED_ACTION:信号強度の変化が起こる放送WIFIホットスポットは、現在のホットスポットの信号強度の最新の変更を取得することができます。

放送を受信した後の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);
    }
}

ブートは、Wi-Fiインターネット回線であれば私たちのテレビ、ブートの無線LAN状態は、開いている、彼らはWIFI_STATE_CHANGED_ACTION、CONFIGURED_NETWORKS_CHANGED_ACTION、NETWORK_STATE_CHANGED_ACTION、SUPPLICANT_STATE_CHANGED_ACTIONを受け取る受け取ることになり、この状態では、認証を起動するために無線LANからのプロセスであり、我々は見ていました我々のコードのプロセスの下で。
WIFI_STATE_CHANGED_ACTIONは内部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();

}  

ここでは、実際に私は、グローバル変数のレコード番号をクリアし、何もしませんでした。その後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);
}

この時点で、wifiManger状態がWIFI_STATE_ENABLEDされます。(あなたが自動接続を有効にする方法を学びたい場合は、独自の無線LANで無線LANに接続し、ACではない最後の判断、前のソースコードを読み取られていない)、その後、我々はより重要constructWifiAccessPoints(ある)機能:

  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;
}

この効果は、主機能WIfiAccessPointを得るために使用され、このクラスは、主に無線LANの情報を格納するために使用されます。最初constructWifiAccessPointsこの関数mWifiManager.getConfiguredNetworksによるリンクが存在する前には、ApMapに保存し、無線LANの情報があったが、その後、スキャンした無線LANを保存します。次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);
        }
    }
}

ここではメインのアップデート無線LAN、IDLEの接続状態:アイドルSCANNING:スキャンは、接続:接続認証:認証...
OBTAINING_IPADDR:取得IPアドレスCONNECTED:接続SUSPENDED:一時停止DISCONNECTING:切断.. 。
ブロックされて失敗しました::一時的に閉鎖(貧弱なネットワーク条件):VERIFYING_POOR_LINKブロックされて失敗切断:切断
CAPTIVE_PORTAL_CHECKを:あなたが二度目にログインする必要があるかどうかを判断するためには、いくつかの州よりも多いです。我々はSUPPLICANT_STATE_CHANGED_ACTION放送を受信すると、処理のhandleEventは、次のように:

         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);

ここでは主に認証が失敗した後に対処無線LANを扱います。この部分はupdateWifiAccessPoints()、次のような外観パッケージ/../フレームワーク/ SRC / COM /../あるフレームワーク/無線LAN / WifiAccessPoint.java、 主に各無線LANの記録詳細については、それぞれが構築します時間ステータスの更新、それはその後、新鮮な、各WifiAccessPointを再構築するために行きます。
WifiAccessPoint(コンテキストコンテキストは、config WifiConfiguration){
loadConfig(設定);
リフレッシュ();
}

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

リフレッシュでは主な理由は、エラーを更新することです:

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;

    }
}

認定直接ラインに保存された無線LANの状態を更新接続されています。それはどのような状態変更通知上位無線LANそれはありますか?これは、イベントを処理するために、このインターフェイスを実装することにより、上層のインタフェースを記述するためにここにパッケージのフレームワーク/ SRC / COM /../フレームワーク/無線LAN / LocalWifiSetting.javaで主に/../あります。私たちは、必要な場合にコールバックトリガします。

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);
        }
    }
}

ここでは無線LANアダプテーション層に比較ロジックは、他の機能は、実質的の意味を理解することができます参照するための基本的な関数名、ほぼ完全である:パッケージで、実質的に/../フレームワーク/ SRC / COM /../フレームワーク/ WIFI / LocalWifiSetting.java 、見つける接続し、無線LANの情報へのアクセス、保存された無線LANを削除する、など

###イーサネットモジュールのドキュメントは
その後、イーサネットプロセスをご紹介します。メインのファイルパス:

パッケージ/../フレームワーク/ SRC / COM /../フレームワーク/イーサネット/ LocalEthCallback.java
パッケージ/../フレームワーク/ SRC / COM /../フレームワーク/イーサネット/ LocalEthernetDevInfo.java
パッケージ/../フレームワーク/ SRC /com/../framework/ethernet/LocalEthManager.java

無線LANと同様に、メインクラスはLocalEthManagerですが、次のように内部は、特定の実装があり、基本的には抽象メソッドとクラスである:4.4ここではMSTARでイーサネットを置くための時間だったので、その時は大の5.0バージョンで発見されますこの部分を達成するための変更変更は、対応する大規模なバージョンに合わせて分析することができ、下のメジャーバージョン/ ehernet /対応/パッケージ/../フレームワーク/アンドロイドを置いている、我々は最初のandroid4.4は分析します。
それは2つの方法で実装することができます。
./framework/hardware/mstar/tv1/src/ethernet/MstarLocalEthManager.java
./framework/hardware/mtk/tv1/src/ethernet/MtkLocalEthManager.java
./framework/hardware/softwinner/ TV1 / SRC /イーサネット/ 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
これらは大きなアンドロイドバージョンは、Androidのバージョンが構成に応じて、大が存在でない場合には、優先されます下、適切なボードやチップのメーカーがかかりますときにコンパイル、具体的な実現LocalEthManager.javaです。

类似与WIFI的流程有点类似、上层通过LocalWifiSetting.getInstance(mContext)获取单例对象:
公共LocalEthManager(コンテキスト・コンテキスト){
IF(DEBUG)
Log.d(TAG、 "LocalEthManager構築物")。
mEthernetManager =(EthernetManager)context.getSystemService(Context.ETHERNET_SERVICE)。
mConnectivityManager =(ConnectivityManager)context.getSystemService(
Context.CONNECTIVITY_SERVICE)。
IntentFilter intentfilter =新しいIntentFilter();
intentfilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)。
context.registerReceiver(mBroadcastReceiver、intentfilter)。
}

主にアッパーを使用し、CONNECTIVITY_ACTION =「android.net.conn.CONNECTIVITY_CHANGE」、放送を受信し、トリガーのコールバック接続状況を聞いて、実際には、イーサネットの実装は単純
=新新BroadcastReceiver(){民間最終BroadcastReceiver mBroadcastReceiverを
公共のボイドonReceive(コンテキストコンテキスト、インテントインテント){
// TODO自動生成されたメソッドスタブ
int型= intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE、ConnectivityManager.TYPE_NONE);
IF(タイプ== ConnectivityManager.TYPE_ETHERNET){
NetworkInfo NetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET );
IF(DEBUG)
Log.d(TAG、 "チェンジアクション国家のEth");
!IF(NetworkInfo = NULL && networkInfo.isConnected()){
Log.d(TAG、 "LocalEthManager.EVENT_ETH_CONNECTED");
dispatchEthEvent(LocalEthManager.EVENT_ETH_CONNECTED)。
}他{
Log.d(TAG、 "LocalEthManager.EVENT_ETH_DISCONNECTED")。
dispatchEthEvent(LocalEthManager.EVENT_ETH_DISCONNECTED)。
}
}
}
}。

その他の機能は、イーサネットは、上位層に関連する情報を取得します。
isEthernetAvailable()---------------イーサネットをサポート
getSavedEthConfigは()---------------イーサネット、IP、および静的なポイントを手に入れます非静的、対応LocalEthernetDevInfoコンストラクト
updateEthDevInfo()----------------イーサネット更新された情報(上位層を使用しないでください)
)(getDhcpInfoを

おすすめ

転載: blog.51cto.com/6433051/2402761