上一篇说完了WifiDisplay的开启流程,开启以后就直接进入扫描状态。
/frameworks/base/services/core/java/com/android/server/display/WifiDisplayController.java
private void updateScanState() {
if (mScanRequested && mWfdEnabled && mDesiredDevice == null) {
if (!mDiscoverPeersInProgress) {
Slog.i(TAG, "Starting Wifi display scan.");
mDiscoverPeersInProgress = true;
handleScanStarted();
tryDiscoverPeers();
}
} else {
if (mDiscoverPeersInProgress) {
// Cancel automatic retry right away.
mHandler.removeCallbacks(mDiscoverPeers);
// Defer actually stopping discovery if we have a connection attempt in progress.
// The wifi display connection attempt often fails if we are not in discovery
// mode. So we allow discovery to continue until we give up trying to connect.
if (mDesiredDevice == null || mDesiredDevice == mConnectedDevice) {
Slog.i(TAG, "Stopping Wifi display scan.");
mDiscoverPeersInProgress = false;
stopPeerDiscovery();
handleScanFinished();
}
}
}
}
handleScanStarted主要就是开启了一个监听器。
private void handleScanStarted() {
mHandler.post(new Runnable() {
@Override
public void run() {
mListener.onScanStarted();
}
});
}
尝试开始发现同等设备,然后返回success,就requestPeers,请求这一步把扫描流程走完再返回来梳理。
private void tryDiscoverPeers() {
mWifiP2pManager.discoverPeers(mWifiP2pChannel, new ActionListener() {
@Override
public void onSuccess() {
if (DEBUG) {
Slog.d(TAG, "Discover peers succeeded. Requesting peers now.");
}
if (mDiscoverPeersInProgress) {
requestPeers();
}
// Retry discover peers periodically until stopped.
mHandler.postDelayed(mDiscoverPeers, DISCOVER_PEERS_INTERVAL_MILLIS);
}
然后下面就是一路函数调用了,和wifi的差不多,一直到supplicant。
/frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
public void discoverPeers(Channel c, ActionListener listener) {
checkChannel(c);
c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener));
}
/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
case WifiP2pManager.DISCOVER_PEERS:
if (mDiscoveryBlocked) {
replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
WifiP2pManager.BUSY);
break;
}
// do not send service discovery request while normal find operation.
clearSupplicantServiceRequest();
if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
sendP2pDiscoveryChangedBroadcast(true);
} else {
replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
WifiP2pManager.ERROR);
}
break;
/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/WifiP2pNative.java
public boolean p2pFind(int timeout) {
return mSupplicantP2pIfaceHal.find(timeout);
}
/frameworks/opt/net/wifi/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
public boolean find(int timeout) {
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("find")) return false;
if (timeout < 0) {
Log.e(TAG, "Invalid timeout value: " + timeout);
return false;
}
SupplicantResult result = new SupplicantResult("find(" + timeout + ")");
try {
result.setResult(mISupplicantP2pIface.find(timeout));
} catch (RemoteException e) {
Log.e(TAG, "ISupplicantP2pIface exception: " + e);
supplicantServiceDiedHandler();
}
return result.isSuccess();
}
}
/hardware/interfaces/wifi/supplicant/1.0/ISupplicantP2pIface.hal
find(uint32_t timeoutInSec) generates (SupplicantStatus status);
/external/wpa_supplicant_8/wpa_supplicant/hidl/1.0/p2p_iface.cpp
Return P2pIface::find(uint32_t timeout_in_sec, find_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::findInternal, _hidl_cb, timeout_in_sec);
}
SupplicantStatus P2pIface::findInternal(uint32_t timeout_in_sec)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
}
uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
if (wpas_p2p_find(
wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
nullptr, search_delay, 0, nullptr, 0)) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
return {SupplicantStatusCode::SUCCESS, ""};
}
/external/wpa_supplicant_8/wpa_supplicant/p2p_supplicant.c
int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay,
u8 seek_cnt, const char **seek_string, int freq)
{
wpas_p2p_clear_pending_action_tx(wpa_s);
wpa_s->p2p_long_listen = 0;
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
wpa_s->p2p_in_provisioning) {
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Reject p2p_find operation%s%s",
(wpa_s->global->p2p_disabled || !wpa_s->global->p2p) ?
" (P2P disabled)" : "",
wpa_s->p2p_in_provisioning ?
" (p2p_in_provisioning)" : "");
return -1;
}
wpa_supplicant_cancel_sched_scan(wpa_s);
return p2p_find(wpa_s->global->p2p, timeout, type,
num_req_dev_types, req_dev_types, dev_id,
search_delay, seek_cnt, seek_string, freq);
}
扫描结果出来以后,如果返回success可以看到执行requestPeers函数,也就是向对端设备发起请求了。
/frameworks/base/services/core/java/com/android/server/display/WifiDisplayController.java
private void tryDiscoverPeers() {
mWifiP2pManager.discoverPeers(mWifiP2pChannel, new ActionListener() {
@Override
public void onSuccess() {
if (DEBUG) {
Slog.d(TAG, "Discover peers succeeded. Requesting peers now.");
}
if (mDiscoverPeersInProgress) {
requestPeers();
}
private void requestPeers() {
mWifiP2pManager.requestPeers(mWifiP2pChannel, new PeerListListener() {
@Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
if (DEBUG) {
Slog.d(TAG, "Received list of peers.");
}
mAvailableWifiDisplayPeers.clear();
for (WifiP2pDevice device : peers.getDeviceList()) {
if (DEBUG) {
Slog.d(TAG, " " + describeWifiP2pDevice(device));
}
if (isWifiDisplay(device)) {
mAvailableWifiDisplayPeers.add(device);
}
}
if (mDiscoverPeersInProgress) {
handleScanResults();
}
}
});
}
关注公众号,获取更多开发必备知识