Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.googlecode.android_scripting.facade.wifi;
     18 
     19 import android.app.Service;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.net.NetworkInfo;
     25 import android.net.wifi.WpsInfo;
     26 import android.net.wifi.p2p.WifiP2pConfig;
     27 import android.net.wifi.p2p.WifiP2pDevice;
     28 import android.net.wifi.p2p.WifiP2pDeviceList;
     29 import android.net.wifi.p2p.WifiP2pGroup;
     30 import android.net.wifi.p2p.WifiP2pGroupList;
     31 import android.net.wifi.p2p.WifiP2pInfo;
     32 import android.net.wifi.p2p.WifiP2pManager;
     33 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
     34 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
     35 import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
     36 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
     37 import android.os.Bundle;
     38 import android.os.Message;
     39 import android.os.Messenger;
     40 import android.os.RemoteException;
     41 
     42 import com.android.internal.util.Protocol;
     43 import com.googlecode.android_scripting.Log;
     44 import com.googlecode.android_scripting.facade.EventFacade;
     45 import com.googlecode.android_scripting.facade.FacadeManager;
     46 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
     47 import com.googlecode.android_scripting.rpc.Rpc;
     48 import com.googlecode.android_scripting.rpc.RpcParameter;
     49 
     50 import java.net.InetAddress;
     51 import java.util.ArrayList;
     52 import java.util.Collection;
     53 import java.util.HashMap;
     54 import java.util.List;
     55 import java.util.Map;
     56 
     57 import org.json.JSONException;
     58 import org.json.JSONObject;
     59 
     60 /**
     61  * WifiP2pManager functions.
     62  */
     63 public class WifiP2pManagerFacade extends RpcReceiver {
     64 
     65     class WifiP2pActionListener implements WifiP2pManager.ActionListener {
     66         private final EventFacade mEventFacade;
     67         private final String mEventType;
     68         private final String TAG;
     69 
     70         public WifiP2pActionListener(EventFacade eventFacade, String tag) {
     71             mEventType = "WifiP2p";
     72             mEventFacade = eventFacade;
     73             TAG = tag;
     74         }
     75 
     76         @Override
     77         public void onSuccess() {
     78             mEventFacade.postEvent(mEventType + TAG + "OnSuccess", null);
     79         }
     80 
     81         @Override
     82         public void onFailure(int reason) {
     83             Log.d("WifiActionListener  " + mEventType);
     84             Bundle msg = new Bundle();
     85             if (reason == WifiP2pManager.P2P_UNSUPPORTED) {
     86                 msg.putString("reason", "P2P_UNSUPPORTED");
     87             } else if (reason == WifiP2pManager.ERROR) {
     88                 msg.putString("reason", "ERROR");
     89             } else if (reason == WifiP2pManager.BUSY) {
     90                 msg.putString("reason", "BUSY");
     91             } else if (reason == WifiP2pManager.NO_SERVICE_REQUESTS) {
     92                 msg.putString("reason", "NO_SERVICE_REQUESTS");
     93             } else {
     94                 msg.putInt("reason", reason);
     95             }
     96             mEventFacade.postEvent(mEventType + TAG + "OnFailure", msg);
     97         }
     98     }
     99 
    100     class WifiP2pConnectionInfoListener implements WifiP2pManager.ConnectionInfoListener {
    101         private final EventFacade mEventFacade;
    102         private final String mEventType;
    103 
    104         public WifiP2pConnectionInfoListener(EventFacade eventFacade) {
    105             mEventType = "WifiP2p";
    106             mEventFacade = eventFacade;
    107         }
    108 
    109         @Override
    110         public void onConnectionInfoAvailable(WifiP2pInfo info) {
    111             Bundle msg = new Bundle();
    112             msg.putBoolean("groupFormed", info.groupFormed);
    113             msg.putBoolean("isGroupOwner", info.isGroupOwner);
    114             InetAddress addr = info.groupOwnerAddress;
    115             String hostName = null;
    116             String hostAddress = null;
    117             if (addr != null) {
    118                 hostName = addr.getHostName();
    119                 hostAddress = addr.getHostAddress();
    120             }
    121             msg.putString("groupOwnerHostName", hostName);
    122             msg.putString("groupOwnerHostAddress", hostAddress);
    123             mEventFacade.postEvent(mEventType + "OnConnectionInfoAvailable", msg);
    124         }
    125     }
    126 
    127     class WifiP2pDnsSdServiceResponseListener implements
    128             WifiP2pManager.DnsSdServiceResponseListener {
    129         private final EventFacade mEventFacade;
    130         private final String mEventType;
    131 
    132         public WifiP2pDnsSdServiceResponseListener(EventFacade eventFacade) {
    133             mEventType = "WifiP2p";
    134             mEventFacade = eventFacade;
    135         }
    136 
    137         @Override
    138         public void onDnsSdServiceAvailable(String instanceName, String registrationType,
    139                 WifiP2pDevice srcDevice) {
    140             Bundle msg = new Bundle();
    141             msg.putString("InstanceName", instanceName);
    142             msg.putString("RegistrationType", registrationType);
    143             msg.putString("SourceDeviceName", srcDevice.deviceName);
    144             msg.putString("SourceDeviceAddress", srcDevice.deviceAddress);
    145             mEventFacade.postEvent(mEventType + "OnDnsSdServiceAvailable", msg);
    146         }
    147     }
    148 
    149     class WifiP2pDnsSdTxtRecordListener implements WifiP2pManager.DnsSdTxtRecordListener {
    150         private final EventFacade mEventFacade;
    151         private final String mEventType;
    152 
    153         public WifiP2pDnsSdTxtRecordListener(EventFacade eventFacade) {
    154             mEventType = "WifiP2p";
    155             mEventFacade = eventFacade;
    156         }
    157 
    158         @Override
    159         public void onDnsSdTxtRecordAvailable(String fullDomainName,
    160                 Map<String, String> txtRecordMap, WifiP2pDevice srcDevice) {
    161             Bundle msg = new Bundle();
    162             msg.putString("FullDomainName", fullDomainName);
    163             Bundle txtMap = new Bundle();
    164             for (String key : txtRecordMap.keySet()) {
    165                 txtMap.putString(key, txtRecordMap.get(key));
    166             }
    167             msg.putBundle("TxtRecordMap", txtMap);
    168             msg.putString("SourceDeviceName", srcDevice.deviceName);
    169             msg.putString("SourceDeviceAddress", srcDevice.deviceAddress);
    170             mEventFacade.postEvent(mEventType + "OnDnsSdTxtRecordAvailable", msg);
    171         }
    172 
    173     }
    174 
    175     class WifiP2pGroupInfoListener implements WifiP2pManager.GroupInfoListener {
    176         private final EventFacade mEventFacade;
    177         private final String mEventType;
    178 
    179         public WifiP2pGroupInfoListener(EventFacade eventFacade) {
    180             mEventType = "WifiP2p";
    181             mEventFacade = eventFacade;
    182         }
    183 
    184         @Override
    185         public void onGroupInfoAvailable(WifiP2pGroup group) {
    186             mEventFacade.postEvent(mEventType + "OnGroupInfoAvailable", parseGroupInfo(group));
    187         }
    188     }
    189 
    190     class WifiP2pPeerListListener implements WifiP2pManager.PeerListListener {
    191         private final EventFacade mEventFacade;
    192 
    193         public WifiP2pPeerListListener(EventFacade eventFacade) {
    194             mEventFacade = eventFacade;
    195         }
    196 
    197         @Override
    198         public void onPeersAvailable(WifiP2pDeviceList newPeers) {
    199             Collection<WifiP2pDevice> devices = newPeers.getDeviceList();
    200             Log.d(devices.toString());
    201             if (devices.size() > 0) {
    202                 mP2pPeers.clear();
    203                 mP2pPeers.addAll(devices);
    204                 Bundle msg = new Bundle();
    205                 msg.putParcelableList("Peers", mP2pPeers);
    206                 mEventFacade.postEvent(mEventType + "OnPeersAvailable", msg);
    207             }
    208         }
    209     }
    210 
    211     class WifiP2pPersistentGroupInfoListener implements WifiP2pManager.PersistentGroupInfoListener {
    212         private final EventFacade mEventFacade;
    213         private final String mEventType;
    214 
    215         public WifiP2pPersistentGroupInfoListener(EventFacade eventFacade) {
    216             mEventType = "WifiP2p";
    217             mEventFacade = eventFacade;
    218         }
    219 
    220         @Override
    221         public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) {
    222             ArrayList<Bundle> gs = new ArrayList<Bundle>();
    223             for (WifiP2pGroup g : groups.getGroupList()) {
    224                 gs.add(parseGroupInfo(g));
    225             }
    226             mEventFacade.postEvent(mEventType + "OnPersistentGroupInfoAvailable", gs);
    227         }
    228 
    229     }
    230 
    231     class WifiP2pStateChangedReceiver extends BroadcastReceiver {
    232         private final EventFacade mEventFacade;
    233         private final Bundle mResults;
    234 
    235         WifiP2pStateChangedReceiver(EventFacade eventFacade) {
    236             mEventFacade = eventFacade;
    237             mResults = new Bundle();
    238         }
    239 
    240         @Override
    241         public void onReceive(Context c, Intent intent) {
    242             String action = intent.getAction();
    243             if (action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) {
    244                 Log.d("Wifi P2p State Changed.");
    245                 int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, 0);
    246                 if (state == WifiP2pManager.WIFI_P2P_STATE_DISABLED) {
    247                     Log.d("Disabled");
    248                     isP2pEnabled = false;
    249                 } else if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
    250                     Log.d("Enabled");
    251                     isP2pEnabled = true;
    252                 }
    253             } else if (action.equals(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)) {
    254                 Log.d("Wifi P2p Peers Changed. Requesting peers.");
    255                 WifiP2pDeviceList peers = intent
    256                         .getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST);
    257                 Log.d(peers.toString());
    258                 wifiP2pRequestPeers();
    259             } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
    260                 Log.d("Wifi P2p Connection Changed.");
    261                 WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
    262                 NetworkInfo networkInfo = intent
    263                         .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
    264                 WifiP2pGroup group = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
    265                 if (networkInfo.isConnected()) {
    266                     Log.d("Wifi P2p Connected.");
    267                     mResults.putParcelable("P2pInfo", p2pInfo);
    268                     mResults.putParcelable("Group", group);
    269                     mEventFacade.postEvent(mEventType + "Connected", mResults);
    270                     mResults.clear();
    271                 } else {
    272                     mEventFacade.postEvent(mEventType + "Disconnected", null);
    273                 }
    274             } else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) {
    275                 Log.d("Wifi P2p This Device Changed.");
    276                 WifiP2pDevice device = intent
    277                         .getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
    278                 mResults.putParcelable("Device", device);
    279                 mEventFacade.postEvent(mEventType + "ThisDeviceChanged", mResults);
    280                 mResults.clear();
    281             } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) {
    282                 Log.d("Wifi P2p Discovery Changed.");
    283                 int state = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, 0);
    284                 if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) {
    285                     Log.d("discovery started.");
    286                 } else if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED) {
    287                     Log.d("discovery stoped.");
    288                 }
    289             }
    290         }
    291     }
    292 
    293     private final static String mEventType = "WifiP2p";
    294 
    295     private WifiP2pManager.Channel mChannel;
    296     private final EventFacade mEventFacade;
    297     private final WifiP2pManager mP2p;
    298     private final WifiP2pStateChangedReceiver mP2pStateChangedReceiver;
    299     private final Service mService;
    300     private final IntentFilter mStateChangeFilter;
    301     private final Map<Integer, WifiP2pServiceRequest> mServiceRequests;
    302 
    303     private boolean isP2pEnabled;
    304     private int mServiceRequestCnt = 0;
    305     private WifiP2pServiceInfo mServiceInfo = null;
    306     private List<WifiP2pDevice> mP2pPeers = new ArrayList<WifiP2pDevice>();
    307 
    308     public WifiP2pManagerFacade(FacadeManager manager) {
    309         super(manager);
    310         mService = manager.getService();
    311         mP2p = (WifiP2pManager) mService.getSystemService(Context.WIFI_P2P_SERVICE);
    312         mEventFacade = manager.getReceiver(EventFacade.class);
    313 
    314         mStateChangeFilter = new IntentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
    315         mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
    316         mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
    317         mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
    318         mStateChangeFilter.setPriority(999);
    319 
    320         mP2pStateChangedReceiver = new WifiP2pStateChangedReceiver(mEventFacade);
    321         mServiceRequests = new HashMap<Integer, WifiP2pServiceRequest>();
    322     }
    323 
    324     public Bundle parseGroupInfo(WifiP2pGroup group) {
    325         Bundle msg = new Bundle();
    326         msg.putString("Interface", group.getInterface());
    327         msg.putString("NetworkName", group.getNetworkName());
    328         msg.putString("Passphrase", group.getPassphrase());
    329         msg.putInt("NetworkId", group.getNetworkId());
    330         msg.putString("OwnerName", group.getOwner().deviceName);
    331         msg.putString("OwnerAddress", group.getOwner().deviceAddress);
    332         return msg;
    333     }
    334 
    335     @Override
    336     public void shutdown() {
    337         mService.unregisterReceiver(mP2pStateChangedReceiver);
    338     }
    339 
    340     @Rpc(description = "Accept p2p connection invitation.")
    341     public void wifiP2pAcceptConnection() throws RemoteException {
    342         Log.d("Accepting p2p connection.");
    343         Messenger m = mP2p.getP2pStateMachineMessenger();
    344         int user_accept = Protocol.BASE_WIFI_P2P_SERVICE + 2;
    345         Message msg = Message.obtain();
    346         msg.what = user_accept;
    347         m.send(msg);
    348     }
    349 
    350     @Rpc(description = "Reject p2p connection invitation.")
    351     public void wifiP2pRejectConnection() throws RemoteException {
    352         Log.d("Rejecting p2p connection.");
    353         Messenger m = mP2p.getP2pStateMachineMessenger();
    354         int user_accept = Protocol.BASE_WIFI_P2P_SERVICE + 3;
    355         Message msg = Message.obtain();
    356         msg.what = user_accept;
    357         m.send(msg);
    358     }
    359 
    360     @Rpc(description = "Register a local service for service discovery. One of the \"CreateXxxServiceInfo functions needs to be called first.\"")
    361     public void wifiP2pAddLocalService() {
    362         mP2p.addLocalService(mChannel, mServiceInfo,
    363                 new WifiP2pActionListener(mEventFacade, "AddLocalService"));
    364     }
    365 
    366     @Rpc(description = "Add a service discovery request.")
    367     public Integer wifiP2pAddServiceRequest(
    368             @RpcParameter(name = "protocolType") Integer protocolType) {
    369         WifiP2pServiceRequest request = WifiP2pServiceRequest.newInstance(protocolType);
    370         mServiceRequestCnt += 1;
    371         mServiceRequests.put(mServiceRequestCnt, request);
    372         mP2p.addServiceRequest(mChannel, request, new WifiP2pActionListener(mEventFacade,
    373                 "AddServiceRequest"));
    374         return mServiceRequestCnt;
    375     }
    376 
    377     @Rpc(description = "Cancel any ongoing connect negotiation.")
    378     public void wifiP2pCancelConnect() {
    379         mP2p.cancelConnect(mChannel, new WifiP2pActionListener(mEventFacade, "CancelConnect"));
    380     }
    381 
    382     @Rpc(description = "Clear all registered local services of service discovery.")
    383     public void wifiP2pClearLocalServices() {
    384         mP2p.clearLocalServices(mChannel,
    385                 new WifiP2pActionListener(mEventFacade, "ClearLocalServices"));
    386     }
    387 
    388     @Rpc(description = "Clear all registered service discovery requests.")
    389     public void wifiP2pClearServiceRequests() {
    390         mP2p.clearServiceRequests(mChannel,
    391                 new WifiP2pActionListener(mEventFacade, "ClearServiceRequests"));
    392     }
    393 
    394     @Rpc(description = "Connects to a discovered wifi p2p device.")
    395     public void wifiP2pConnect(@RpcParameter(name = "deviceId") String deviceId) {
    396         for (WifiP2pDevice d : mP2pPeers) {
    397             if (wifiP2pDeviceMatches(d, deviceId)) {
    398                 WifiP2pConfig config = new WifiP2pConfig();
    399                 config.deviceAddress = d.deviceAddress;
    400                 config.wps.setup = WpsInfo.PBC;
    401                 mP2p.connect(mChannel, config,
    402                         new WifiP2pActionListener(mEventFacade, "Connect"));
    403             }
    404         }
    405     }
    406 
    407     @Rpc(description = "Create a Bonjour service info object to be used for wifiP2pAddLocalService.")
    408     public void wifiP2pCreateBonjourServiceInfo(
    409             @RpcParameter(name = "instanceName") String instanceName,
    410             @RpcParameter(name = "serviceType") String serviceType,
    411             @RpcParameter(name = "txtMap") JSONObject txtMap) throws JSONException {
    412         Map<String, String> map = new HashMap<String, String>();
    413         for (String key : txtMap.keySet()) {
    414             map.put(key, txtMap.getString(key));
    415         }
    416         mServiceInfo = WifiP2pDnsSdServiceInfo.newInstance(instanceName, serviceType, map);
    417     }
    418 
    419     @Rpc(description = "Create a wifi p2p group.")
    420     public void wifiP2pCreateGroup() {
    421         mP2p.createGroup(mChannel, new WifiP2pActionListener(mEventFacade, "CreatGroup"));
    422     }
    423 
    424     @Rpc(description = "Create a Upnp service info object to be used for wifiP2pAddLocalService.")
    425     public void wifiP2pCreateUpnpServiceInfo(
    426             @RpcParameter(name = "uuid") String uuid,
    427             @RpcParameter(name = "device") String device,
    428             @RpcParameter(name = "services") List<String> services) {
    429         mServiceInfo = WifiP2pUpnpServiceInfo.newInstance(uuid, device, services);
    430     }
    431 
    432     @Rpc(description = "Delete a stored persistent group from the system settings.")
    433     public void wifiP2pDeletePersistentGroup(@RpcParameter(name = "netId") Integer netId) {
    434         mP2p.deletePersistentGroup(mChannel, netId,
    435                 new WifiP2pActionListener(mEventFacade, "DeletePersistentGroup"));
    436     }
    437 
    438     private boolean wifiP2pDeviceMatches(WifiP2pDevice d, String deviceId) {
    439         return d.deviceName.equals(deviceId) || d.deviceAddress.equals(deviceId);
    440     }
    441 
    442     @Rpc(description = "Start peers discovery for wifi p2p.")
    443     public void wifiP2pDiscoverPeers() {
    444         mP2p.discoverPeers(mChannel, new WifiP2pActionListener(mEventFacade, "DiscoverPeers"));
    445     }
    446 
    447     @Rpc(description = "Initiate service discovery.")
    448     public void wifiP2pDiscoverServices() {
    449         mP2p.discoverServices(mChannel,
    450                 new WifiP2pActionListener(mEventFacade, "DiscoverServices"));
    451     }
    452 
    453     @Rpc(description = "Initialize wifi p2p. Must be called before any other p2p functions.")
    454     public void wifiP2pInitialize() {
    455         mService.registerReceiver(mP2pStateChangedReceiver, mStateChangeFilter);
    456         mChannel = mP2p.initialize(mService, mService.getMainLooper(), null);
    457     }
    458 
    459     @Rpc(description = "Returns true if wifi p2p is enabled, false otherwise.")
    460     public Boolean wifiP2pIsEnabled() {
    461         return isP2pEnabled;
    462     }
    463 
    464     @Rpc(description = "Remove the current p2p group.")
    465     public void wifiP2pRemoveGroup() {
    466         mP2p.removeGroup(mChannel, new WifiP2pActionListener(mEventFacade, "RemoveGroup"));
    467     }
    468 
    469     @Rpc(description = "Remove a registered local service added with wifiP2pAddLocalService.")
    470     public void wifiP2pRemoveLocalService() {
    471         mP2p.removeLocalService(mChannel, mServiceInfo,
    472                 new WifiP2pActionListener(mEventFacade, "RemoveLocalService"));
    473     }
    474 
    475     @Rpc(description = "Remove a service discovery request.")
    476     public void wifiP2pRemoveServiceRequest(@RpcParameter(name = "index") Integer index) {
    477         mP2p.removeServiceRequest(mChannel, mServiceRequests.remove(index),
    478                 new WifiP2pActionListener(mEventFacade, "RemoveServiceRequest"));
    479     }
    480 
    481     @Rpc(description = "Request device connection info.")
    482     public void wifiP2pRequestConnectionInfo() {
    483         mP2p.requestConnectionInfo(mChannel, new WifiP2pConnectionInfoListener(mEventFacade));
    484     }
    485 
    486     @Rpc(description = "Create a wifi p2p group.")
    487     public void wifiP2pRequestGroupInfo() {
    488         mP2p.requestGroupInfo(mChannel, new WifiP2pGroupInfoListener(mEventFacade));
    489     }
    490 
    491     @Rpc(description = "Request peers that are discovered for wifi p2p.")
    492     public void wifiP2pRequestPeers() {
    493         mP2p.requestPeers(mChannel, new WifiP2pPeerListListener(mEventFacade));
    494     }
    495 
    496     @Rpc(description = "Request a list of all the persistent p2p groups stored in system.")
    497     public void wifiP2pRequestPersistentGroupInfo() {
    498         mP2p.requestPersistentGroupInfo(mChannel,
    499                 new WifiP2pPersistentGroupInfoListener(mEventFacade));
    500     }
    501 
    502     @Rpc(description = "Set p2p device name.")
    503     public void wifiP2pSetDeviceName(@RpcParameter(name = "devName") String devName) {
    504         mP2p.setDeviceName(mChannel, devName,
    505                 new WifiP2pActionListener(mEventFacade, "SetDeviceName"));
    506     }
    507 
    508     @Rpc(description = "Register a callback to be invoked on receiving Bonjour service discovery response.")
    509     public void wifiP2pSetDnsSdResponseListeners() {
    510         mP2p.setDnsSdResponseListeners(mChannel,
    511                 new WifiP2pDnsSdServiceResponseListener(mEventFacade),
    512                 new WifiP2pDnsSdTxtRecordListener(mEventFacade));
    513     }
    514 
    515     @Rpc(description = "Stop an ongoing peer discovery.")
    516     public void wifiP2pStopPeerDiscovery() {
    517         mP2p.stopPeerDiscovery(mChannel,
    518                 new WifiP2pActionListener(mEventFacade, "StopPeerDiscovery"));
    519     }
    520 
    521 }
    522