一:android4.0.3 wifi p2p各层次的代码分布

JAVA app -> JAVA Manager -> JAVA Service -> JNI -> HAL stub

 

JAVA app代码位置:

Android sdk\samples\android-15\WiFiDirectDemo

 

JAVA Manager代码位置:

frameworks\base\wifi\java\android\net\wifi\p2p\WifiP2pManager.java

 

JAVA Service代码位置:

frameworks\base\wifi\java\android\net\wifi\p2p\WifiP2pService.java

frameworks\base\wifi\java\android\net\wifi\WifiNative.java

 

JNI代码位置:

Frameworks\base\core\jni\android_net_wifi_Wifi.cpp

 

HAL stub代码位置:

hardware\libhardware_legacy\wifi\wifi.c

hardware\libhardware_legacy\include\hardware_legacy\wifi.h

 

Setting代码位置:

Packages\apps\Settings\src\com\android\settings\wifi\p2p

 

JAVA Manager与JAVA Service之间的通信需要通过AIDL来实现的,即IWifiP2pManager.aidl,它用来定义接口,经过aidl工具会被编译成IWifiP2pManager.java文件,JAVA Service会去实现这些接口供Manager调用。

JAVA Service通过调用android\net\wifi目录下的WifiNative.java文件里面的native方法,从而调用到JNI层。JNI层就是去实现WifiNative.java中那些native定义的方法。

 

二:分析代码:

JAVA app主要做了以下几件事情:

A.enable wifi p2p,这个实际上是去调用setting的功能。

B.扫描wifi p2p设备,并显示在一个列表中。

C.在列表中选择某个设备进行连接,连接后显示GO的信息,并且根据角色的不同做不同的 事情,GO开启一个新的线程FileServerAsyncTask用于

  // After the group negotiation, we assign the group owner as the file

 // server. The file server is single threaded, single connection   server socket.

而client则是

  // The other device acts as the client. In this case, we enable the

  // get file button.

   这样就可以实现文件的传送了。

D.断开连接

 

1.我以B为例,说明层次间的调用过程

  1)文件WiFiDirectActivity.java

a) JAVA app通过

intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);     intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);         intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);     intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

    receiver=newWiFiDirectBroadcastReceiver(manager,channel,this);

registerReceiver(receiver,intentFilter);

注册自己关心的几类广播事件。

b) 当用户点击搜索图标后,就会调用manager.discoverPeers()

2)文件WifiP2pManager.java

JAVA Manger层的discoverPeers()函数会被调用到,它通过

sendMessage(DISCOVER_PEERS, 0, c.putListener(listener)),把命令发送到JAVA  Service。

3)文件WifiP2pService.java

JAVA Service层根据自己的状态机的当前状态处理JAVA Manger层发送过来的 DISCOVER_PEERS请求。

以P2pEnabledState状态为例,processMessage()处理函数根据message.what进入到

WifiP2pManager.DISCOVER_PEERS case,调用WifiNative.p2pFind()。

4)文件WifiNative.java

p2pFind()会去调用native函数doBooleanCommand(),该函数在此文件中只有native的  声明,它的定义是在JNI层。

5)文件android_net_wifi_Wifi.cpp

doBooleanCommand()函数在这里定义,它通过调用自己文件的doCommand()函数,再调 用::wifi_command(cmd, replybuf, &reply_len)。

6)文件wifi.c

wifi_command()是HAL层的函数,它通过调用wifi_send_command(),把请求发送到    wpa_supplicant,wpa_supplicant就会与wifi driver通信。

这样顺序调用就完成了,然后一层层return回去,到3)的WifiNative.p2pFind调用处。

根据调用返回的结果判断是DISCOVER_PEERS_SUCCEEDED或者是

DISCOVER_PEERS_FAILED,这里以成功为例。在这里JAVA Service层通过

replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,

WifiP2pManager.ERROR);

把消息送回到JAVA Manger层。

7)文件WifiP2pManager.java

handleMessage()函数用于接收JAVA Service层返回的消息,通过对message.what的判 断,进入到case WifiP2pManager.DISCOVER_PEERS_SUCCEEDED,然后调用

((ActionListener) listener).onSuccess()。其中ActionListener是一个interface.

8)文件WiFiDirectActivity.java

JAVA app层有重写JAVA Manger层的interfaceActionListener的方法,所以,最后调用到的是JAVA app中的onSuccess()。

 

2.接收service发来的广播事件

1)文件WifiP2pService.java

前面提到JAVA app有注册自己关心的几类广播事件。

当前JAVA Service处在P2pEnabledState状态,

当它收到WifiMonitor.P2P_DEVICE_FOUND_EVENT事件后,会调用    sendP2pPeersChangedBroadcast()把消息广播出去。

2)WiFiDirectBroadcastReceiver.java

onReceive()函数会接收到注册过的广播消息。

 

3.注册回调函数

1)文件WiFiDirectBroadcastReceiver.java

前面讲到onReceive()接收到JAVA Service发来的广播,然后它通过

WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)判断

后,调用manager.requestPeers(channel, (PeerListListener)                                       activity.getFragmentManager()

                       .findFragmentById(R.id.frag_list)),

这个函数也会一层层的最终调用到底层,该函数的第2个参数实际上是注册一个  回凋函数,因为PeerListListener是一个interface,它有个 onPeersAvailable()方法。

2)文件WifiP2pManager.java

当JAVA Manger的handleMessage()收到JAVA Service发送过来的

WifiP2pManager.RESPONSE_PEERS事件后,就会调用之前注册的回凋函数

((PeerListListener) listener).onPeersAvailable(peers),

因为PeerListListener是interface,实际上是调用到了它的实现类的函数,即   DeviceListFragment.java文件中的onPeersAvailable()

3)文件DeviceListFragment.java

onPeersAvailable()函数被调用,它负责get device list,从而让GUI显示出来。

 

补充:

External\wpa_supplicant\wpa_ctrl.h 提供接口给HAL层与driver通信。

 

frameworks\base\core\java\com\android\internal\util\StateMachine.java

frameworks\base\core\java\com\android\internal\util\State.java

这两个类在JAVA Service有使用到。

 

 

在JAVA Service层中的状态机中,带WifiP2pManager的message是JAVA Manger层发送过来的,带WifiMonitor是底层发送过来的。

 

JAVA Service层状态机关系:

Android的class StateMachine有层的概念即父状态和子状态,通过

addState(A, B)函数后,A就成为了B的子状态。

 

 


mDefaultState



mP2pNotSupportedState 



mP2pDisablingState



mP2pDisabledState



mP2pEnablingState



mInactiveState



mP2pEnabledState



mWaitForUserActionState



mWaitForWifiDisableState



mGroupNegotiationState



mGroupCreatedState


 

 

A去连接B:

 

A device:app层调用JAVA Manger的connect()函数(如果当前的设备不是p2p组的成员,那么这个函数就发送group negotiation请求;如果这个设备已经是p2p组的成员,或者自己创建了一个组通过createGroup(),那么这个函数就发送邀请请求),这个函数有个参数是WifiP2pConfig config,它包含了例如自己的MAC,用什么方式连接等一些信息。

通过JAVA Manger的中转,会到达JAVA Service层的P2pEnabledState状态下,这个状态下的处理函数收到WifiP2pManager.CONNECT后,通过调用

WifiNative.p2pConnect(mSavedConnectConfig, join),一层层往底层调用,调用会根据情况是否返回一个PIN。这样一个group negotiation请求就发送出去了。

如果返回PIN则通过

notifyWpsPin(pin, mSavedConnectConfig.deviceAddress),会以AlertDialog的方式显示出来。

 

B device:JAVA Service层处在InactiveState状态下,收到了来自底层的

WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT消息,该消息表示有设备请求GO协商。

收到消息notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig)函数被调用,该显示AlertDialog,用于用户同意或者取消GO协商,如果对方是PIN方式,那么AlertDialog上面会有输入框显示,如果是PBC那么输入框就隐藏。


GroupNegotiationState



P2pEnabledState



P2pDisablingState



InactiveState



P2pDisabledState



WaitForUserActionState



WaitForDisabledState



P2pEnablingState



WiFiP2pManager.

ENABLE_P2P(wifi is opened)



WIFI_DISABLE_USER_REJECT



WIFI_DISABLE_USER_ACCEPT



WiFiP2pManager.ENABLE_P2P(wifi is closed)



startP2pSupplication() successful?



Yes



No



WiFiMonitor.SUP_CONNECTION_EVENT



GroupCreatedState



WiFiP2pManager.CREATE_GROUP



GROUP_NEGOTIATION_TIMEOUT



WiFiP2pManager.CONNECT



WiFiManager.DISABLE_P2p



WiFiMonitor.SUP_DISCONNECTION_EVENT



WiFiMonitor.P2P_group_started_event



WiFiMonitor.SUP_DISCONNECTION_EVENT



WifiMonitor.SUP_DISCONNECTION_EVENT


 

该图为JAVA Service层的状态图,该状态图只列出引起状态变化的事件,不引起状态变化的事件暂不列出,请参考代码。


HAL层与driver通信 wpa_supplicant???