/* * Copyright 2016 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.physical_web.physicalweb; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.WifiP2pManager.Channel; import android.net.wifi.p2p.WifiP2pManager.PeerListListener; /** * This class is for using WifiDirect to discover Physical Web * Devices through peer discovery. */ class WifiUrlDeviceDiscoverer extends UrlDeviceDiscoverer { private static final String TAG = WifiUrlDeviceDiscoverer.class.getSimpleName(); private Context mContext; private WifiP2pManager mManager; private Channel mChannel; private IntentFilter mIntentFilter = new IntentFilter(); private boolean mIsRunning = false; private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action) && mManager != null) { mManager.requestPeers(mChannel, mPeerListener); } } }; private final PeerListListener mPeerListener = new PeerListListener() { @Override public void onPeersAvailable(WifiP2pDeviceList list) { Log.d(TAG, list.toString()); for (WifiP2pDevice device : list.getDeviceList()) { Utils.WifiDirectInfo info = Utils.parseWifiDirectName(device.deviceName); if (info != null) { String name = info.title; int port = info.port; reportUrlDevice(createUrlDeviceBuilder("WifiDirect" + name, device.deviceAddress + ":" + port) .setWifiAddress(device.deviceAddress) .setWifiPort(port) .setTitle(name) .setDescription("") .setDeviceType(Utils.WIFI_DIRECT_DEVICE_TYPE) .build()); } } } }; public WifiUrlDeviceDiscoverer(Context context) { mContext = context; } @Override public synchronized void startScanImpl() { mManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); mContext.registerReceiver(mReceiver, intentFilter); mIsRunning = true; discoverHelper(true); } private void discoverHelper(boolean retry) { mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { } @Override public void onFailure(int reasonCode) { if (retry && reasonCode == WifiP2pManager.BUSY) { mManager.cancelConnect(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG, "cancel connect call success"); if (mIsRunning) { discoverHelper(false); } } @Override public void onFailure(int reason) { Log.d(TAG, "cancel connect call fail " + reason); } }); } } }); } @Override public synchronized void stopScanImpl() { mIsRunning = false; mContext.unregisterReceiver(mReceiver); mManager.stopPeerDiscovery(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { Log.d(TAG, "stop discovering"); } @Override public void onFailure(int reasonCode) { Log.d(TAG, "stop discovery failed " + reasonCode); } }); } }