• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 android.net.wifi.p2p;
18 
19 import android.annotation.SdkConstant;
20 import android.annotation.SdkConstant.SdkConstantType;
21 import android.content.Context;
22 import android.net.ConnectivityManager;
23 import android.net.IConnectivityManager;
24 import android.net.wifi.WpsInfo;
25 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
26 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse;
27 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
28 import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
29 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
30 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
31 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
32 import android.os.Binder;
33 import android.os.Bundle;
34 import android.os.IBinder;
35 import android.os.Handler;
36 import android.os.Looper;
37 import android.os.Message;
38 import android.os.Messenger;
39 import android.os.RemoteException;
40 import android.os.ServiceManager;
41 import android.os.WorkSource;
42 import android.text.TextUtils;
43 import android.util.Log;
44 
45 import com.android.internal.util.AsyncChannel;
46 import com.android.internal.util.Protocol;
47 
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.Map;
51 
52 /**
53  * This class provides the API for managing Wi-Fi peer-to-peer connectivity. This lets an
54  * application discover available peers, setup connection to peers and query for the list of peers.
55  * When a p2p connection is formed over wifi, the device continues to maintain the uplink
56  * connection over mobile or any other available network for internet connectivity on the device.
57  *
58  * <p> The API is asynchronous and responses to requests from an application are on listener
59  * callbacks provided by the application. The application needs to do an initialization with
60  * {@link #initialize} before doing any p2p operation.
61  *
62  * <p> Most application calls need a {@link ActionListener} instance for receiving callbacks
63  * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}. Action callbacks
64  * indicate whether the initiation of the action was a success or a failure.
65  * Upon failure, the reason of failure can be one of {@link #ERROR}, {@link #P2P_UNSUPPORTED}
66  * or {@link #BUSY}.
67  *
68  * <p> An application can initiate discovery of peers with {@link #discoverPeers}. An initiated
69  * discovery request from an application stays active until the device starts connecting to a peer
70  * ,forms a p2p group or there is an explicit {@link #stopPeerDiscovery}.
71  * Applications can listen to {@link #WIFI_P2P_DISCOVERY_CHANGED_ACTION} to know if a peer-to-peer
72  * discovery is running or stopped. Additionally, {@link #WIFI_P2P_PEERS_CHANGED_ACTION} indicates
73  * if the peer list has changed.
74  *
75  * <p> When an application needs to fetch the current list of peers, it can request the list
76  * of peers with {@link #requestPeers}. When the peer list is available
77  * {@link PeerListListener#onPeersAvailable} is called with the device list.
78  *
79  * <p> An application can initiate a connection request to a peer through {@link #connect}. See
80  * {@link WifiP2pConfig} for details on setting up the configuration. For communication with legacy
81  * Wi-Fi devices that do not support p2p, an app can create a group using {@link #createGroup}
82  * which creates an access point whose details can be fetched with {@link #requestGroupInfo}.
83  *
84  * <p> After a successful group formation through {@link #createGroup} or through {@link #connect},
85  * use {@link #requestConnectionInfo} to fetch the connection details. The connection info
86  * {@link WifiP2pInfo} contains the address of the group owner
87  * {@link WifiP2pInfo#groupOwnerAddress} and a flag {@link WifiP2pInfo#isGroupOwner} to indicate
88  * if the current device is a p2p group owner. A p2p client can thus communicate with
89  * the p2p group owner through a socket connection.
90  *
91  * <p> With peer discovery using {@link  #discoverPeers}, an application discovers the neighboring
92  * peers, but has no good way to figure out which peer to establish a connection with. For example,
93  * if a game application is interested in finding all the neighboring peers that are also running
94  * the same game, it has no way to find out until after the connection is setup. Pre-association
95  * service discovery is meant to address this issue of filtering the peers based on the running
96  * services.
97  *
98  * <p>With pre-association service discovery, an application can advertise a service for a
99  * application on a peer device prior to a connection setup between the devices.
100  * Currently, DNS based service discovery (Bonjour) and Upnp are the higher layer protocols
101  * supported. Get Bonjour resources at dns-sd.org and Upnp resources at upnp.org
102  * As an example, a video application can discover a Upnp capable media renderer
103  * prior to setting up a Wi-fi p2p connection with the device.
104  *
105  * <p> An application can advertise a Upnp or a Bonjour service with a call to
106  * {@link #addLocalService}. After a local service is added,
107  * the framework automatically responds to a peer application discovering the service prior
108  * to establishing a p2p connection. A call to {@link #removeLocalService} removes a local
109  * service and {@link #clearLocalServices} can be used to clear all local services.
110  *
111  * <p> An application that is looking for peer devices that support certain services
112  * can do so with a call to  {@link #discoverServices}. Prior to initiating the discovery,
113  * application can add service discovery request with a call to {@link #addServiceRequest},
114  * remove a service discovery request with a call to {@link #removeServiceRequest} or clear
115  * all requests with a call to {@link #clearServiceRequests}. When no service requests remain,
116  * a previously running service discovery will stop.
117  *
118  * The application is notified of a result of service discovery request through listener callbacks
119  * set through {@link #setDnsSdResponseListeners} for Bonjour or
120  * {@link #setUpnpServiceResponseListener} for Upnp.
121  *
122  * <p class="note"><strong>Note:</strong>
123  * Registering an application handler with {@link #initialize} requires the permissions
124  * {@link android.Manifest.permission#ACCESS_WIFI_STATE} and
125  * {@link android.Manifest.permission#CHANGE_WIFI_STATE} to perform any further peer-to-peer
126  * operations.
127  *
128  * Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
129  * Context.getSystemService(Context.WIFI_P2P_SERVICE)}.
130  *
131  * {@see WifiP2pConfig}
132  * {@see WifiP2pInfo}
133  * {@see WifiP2pGroup}
134  * {@see WifiP2pDevice}
135  * {@see WifiP2pDeviceList}
136  * {@see android.net.wifi.WpsInfo}
137  */
138 public class WifiP2pManager {
139     private static final String TAG = "WifiP2pManager";
140     /**
141      * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. An
142      * extra {@link #EXTRA_WIFI_STATE} provides the state information as int.
143      *
144      * @see #EXTRA_WIFI_STATE
145      */
146     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
147     public static final String WIFI_P2P_STATE_CHANGED_ACTION =
148         "android.net.wifi.p2p.STATE_CHANGED";
149 
150     /**
151      * The lookup key for an int that indicates whether Wi-Fi p2p is enabled or disabled.
152      * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
153      *
154      * @see #WIFI_P2P_STATE_DISABLED
155      * @see #WIFI_P2P_STATE_ENABLED
156      */
157     public static final String EXTRA_WIFI_STATE = "wifi_p2p_state";
158 
159     /**
160      * Wi-Fi p2p is disabled.
161      *
162      * @see #WIFI_P2P_STATE_CHANGED_ACTION
163      */
164     public static final int WIFI_P2P_STATE_DISABLED = 1;
165 
166     /**
167      * Wi-Fi p2p is enabled.
168      *
169      * @see #WIFI_P2P_STATE_CHANGED_ACTION
170      */
171     public static final int WIFI_P2P_STATE_ENABLED = 2;
172 
173     /**
174      * Broadcast intent action indicating that the state of Wi-Fi p2p connectivity
175      * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in
176      * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides
177      * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides
178      * the details of the group.
179      *
180      * @see #EXTRA_WIFI_P2P_INFO
181      * @see #EXTRA_NETWORK_INFO
182      * @see #EXTRA_WIFI_P2P_GROUP
183      */
184     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
185     public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION =
186         "android.net.wifi.p2p.CONNECTION_STATE_CHANGE";
187 
188     /**
189      * The lookup key for a {@link android.net.wifi.p2p.WifiP2pInfo} object
190      * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
191      */
192     public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo";
193 
194     /**
195      * The lookup key for a {@link android.net.NetworkInfo} object associated with the
196      * p2p network. Retrieve with
197      * {@link android.content.Intent#getParcelableExtra(String)}.
198      */
199     public static final String EXTRA_NETWORK_INFO = "networkInfo";
200 
201     /**
202      * The lookup key for a {@link android.net.wifi.p2p.WifiP2pGroup} object
203      * associated with the p2p network. Retrieve with
204      * {@link android.content.Intent#getParcelableExtra(String)}.
205      */
206     public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo";
207 
208     /**
209      * Broadcast intent action indicating that the available peer list has changed. This
210      * can be sent as a result of peers being found, lost or updated.
211      *
212      * <p> An extra {@link #EXTRA_P2P_DEVICE_LIST} provides the full list of
213      * current peers. The full list of peers can also be obtained any time with
214      * {@link #requestPeers}.
215      *
216      * @see #EXTRA_P2P_DEVICE_LIST
217      */
218     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
219     public static final String WIFI_P2P_PEERS_CHANGED_ACTION =
220         "android.net.wifi.p2p.PEERS_CHANGED";
221 
222      /**
223       * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDeviceList} object representing
224       * the new peer list when {@link #WIFI_P2P_PEERS_CHANGED_ACTION} broadcast is sent.
225       *
226       * <p>Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
227       */
228      public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList";
229 
230     /**
231      * Broadcast intent action indicating that peer discovery has either started or stopped.
232      * One extra {@link #EXTRA_DISCOVERY_STATE} indicates whether discovery has started
233      * or stopped.
234      *
235      * <p>Note that discovery will be stopped during a connection setup. If the application tries
236      * to re-initiate discovery during this time, it can fail.
237      */
238     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
239     public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION =
240         "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE";
241 
242     /**
243      * The lookup key for an int that indicates whether p2p discovery has started or stopped.
244      * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
245      *
246      * @see #WIFI_P2P_DISCOVERY_STARTED
247      * @see #WIFI_P2P_DISCOVERY_STOPPED
248      */
249     public static final String EXTRA_DISCOVERY_STATE = "discoveryState";
250 
251     /**
252      * p2p discovery has stopped
253      *
254      * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION
255      */
256     public static final int WIFI_P2P_DISCOVERY_STOPPED = 1;
257 
258     /**
259      * p2p discovery has started
260      *
261      * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION
262      */
263     public static final int WIFI_P2P_DISCOVERY_STARTED = 2;
264 
265     /**
266      * Broadcast intent action indicating that this device details have changed.
267      */
268     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
269     public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION =
270         "android.net.wifi.p2p.THIS_DEVICE_CHANGED";
271 
272     /**
273      * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDevice} object
274      * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}.
275      */
276     public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice";
277 
278     /**
279      * Broadcast intent action indicating that remembered persistent groups have changed.
280      * @hide
281      */
282     public static final String WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION =
283         "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED";
284 
285     IWifiP2pManager mService;
286 
287     private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER;
288 
289     /** @hide */
290     public static final int DISCOVER_PEERS                          = BASE + 1;
291     /** @hide */
292     public static final int DISCOVER_PEERS_FAILED                   = BASE + 2;
293     /** @hide */
294     public static final int DISCOVER_PEERS_SUCCEEDED                = BASE + 3;
295 
296     /** @hide */
297     public static final int STOP_DISCOVERY                          = BASE + 4;
298     /** @hide */
299     public static final int STOP_DISCOVERY_FAILED                   = BASE + 5;
300     /** @hide */
301     public static final int STOP_DISCOVERY_SUCCEEDED                = BASE + 6;
302 
303     /** @hide */
304     public static final int CONNECT                                 = BASE + 7;
305     /** @hide */
306     public static final int CONNECT_FAILED                          = BASE + 8;
307     /** @hide */
308     public static final int CONNECT_SUCCEEDED                       = BASE + 9;
309 
310     /** @hide */
311     public static final int CANCEL_CONNECT                          = BASE + 10;
312     /** @hide */
313     public static final int CANCEL_CONNECT_FAILED                   = BASE + 11;
314     /** @hide */
315     public static final int CANCEL_CONNECT_SUCCEEDED                = BASE + 12;
316 
317     /** @hide */
318     public static final int CREATE_GROUP                            = BASE + 13;
319     /** @hide */
320     public static final int CREATE_GROUP_FAILED                     = BASE + 14;
321     /** @hide */
322     public static final int CREATE_GROUP_SUCCEEDED                  = BASE + 15;
323 
324     /** @hide */
325     public static final int REMOVE_GROUP                            = BASE + 16;
326     /** @hide */
327     public static final int REMOVE_GROUP_FAILED                     = BASE + 17;
328     /** @hide */
329     public static final int REMOVE_GROUP_SUCCEEDED                  = BASE + 18;
330 
331     /** @hide */
332     public static final int REQUEST_PEERS                           = BASE + 19;
333     /** @hide */
334     public static final int RESPONSE_PEERS                          = BASE + 20;
335 
336     /** @hide */
337     public static final int REQUEST_CONNECTION_INFO                 = BASE + 21;
338     /** @hide */
339     public static final int RESPONSE_CONNECTION_INFO                = BASE + 22;
340 
341     /** @hide */
342     public static final int REQUEST_GROUP_INFO                      = BASE + 23;
343     /** @hide */
344     public static final int RESPONSE_GROUP_INFO                     = BASE + 24;
345 
346     /** @hide */
347     public static final int ADD_LOCAL_SERVICE                       = BASE + 28;
348     /** @hide */
349     public static final int ADD_LOCAL_SERVICE_FAILED                = BASE + 29;
350     /** @hide */
351     public static final int ADD_LOCAL_SERVICE_SUCCEEDED             = BASE + 30;
352 
353     /** @hide */
354     public static final int REMOVE_LOCAL_SERVICE                    = BASE + 31;
355     /** @hide */
356     public static final int REMOVE_LOCAL_SERVICE_FAILED             = BASE + 32;
357     /** @hide */
358     public static final int REMOVE_LOCAL_SERVICE_SUCCEEDED          = BASE + 33;
359 
360     /** @hide */
361     public static final int CLEAR_LOCAL_SERVICES                    = BASE + 34;
362     /** @hide */
363     public static final int CLEAR_LOCAL_SERVICES_FAILED             = BASE + 35;
364     /** @hide */
365     public static final int CLEAR_LOCAL_SERVICES_SUCCEEDED          = BASE + 36;
366 
367     /** @hide */
368     public static final int ADD_SERVICE_REQUEST                     = BASE + 37;
369     /** @hide */
370     public static final int ADD_SERVICE_REQUEST_FAILED              = BASE + 38;
371     /** @hide */
372     public static final int ADD_SERVICE_REQUEST_SUCCEEDED           = BASE + 39;
373 
374     /** @hide */
375     public static final int REMOVE_SERVICE_REQUEST                  = BASE + 40;
376     /** @hide */
377     public static final int REMOVE_SERVICE_REQUEST_FAILED           = BASE + 41;
378     /** @hide */
379     public static final int REMOVE_SERVICE_REQUEST_SUCCEEDED        = BASE + 42;
380 
381     /** @hide */
382     public static final int CLEAR_SERVICE_REQUESTS                  = BASE + 43;
383     /** @hide */
384     public static final int CLEAR_SERVICE_REQUESTS_FAILED           = BASE + 44;
385     /** @hide */
386     public static final int CLEAR_SERVICE_REQUESTS_SUCCEEDED        = BASE + 45;
387 
388     /** @hide */
389     public static final int DISCOVER_SERVICES                       = BASE + 46;
390     /** @hide */
391     public static final int DISCOVER_SERVICES_FAILED                = BASE + 47;
392     /** @hide */
393     public static final int DISCOVER_SERVICES_SUCCEEDED             = BASE + 48;
394 
395     /** @hide */
396     public static final int PING                                    = BASE + 49;
397 
398     /** @hide */
399     public static final int RESPONSE_SERVICE                        = BASE + 50;
400 
401     /** @hide */
402     public static final int SET_DEVICE_NAME                         = BASE + 51;
403     /** @hide */
404     public static final int SET_DEVICE_NAME_FAILED                  = BASE + 52;
405     /** @hide */
406     public static final int SET_DEVICE_NAME_SUCCEEDED               = BASE + 53;
407 
408     /** @hide */
409     public static final int DELETE_PERSISTENT_GROUP                 = BASE + 54;
410     /** @hide */
411     public static final int DELETE_PERSISTENT_GROUP_FAILED          = BASE + 55;
412     /** @hide */
413     public static final int DELETE_PERSISTENT_GROUP_SUCCEEDED       = BASE + 56;
414 
415     /** @hide */
416     public static final int REQUEST_PERSISTENT_GROUP_INFO           = BASE + 57;
417     /** @hide */
418     public static final int RESPONSE_PERSISTENT_GROUP_INFO          = BASE + 58;
419 
420     /** @hide */
421     public static final int SET_WFD_INFO                            = BASE + 59;
422     /** @hide */
423     public static final int SET_WFD_INFO_FAILED                     = BASE + 60;
424     /** @hide */
425     public static final int SET_WFD_INFO_SUCCEEDED                  = BASE + 61;
426 
427     /** @hide */
428     public static final int START_WPS                               = BASE + 62;
429     /** @hide */
430     public static final int START_WPS_FAILED                        = BASE + 63;
431     /** @hide */
432     public static final int START_WPS_SUCCEEDED                     = BASE + 64;
433 
434     /** @hide */
435     public static final int START_LISTEN                            = BASE + 65;
436     /** @hide */
437     public static final int START_LISTEN_FAILED                     = BASE + 66;
438     /** @hide */
439     public static final int START_LISTEN_SUCCEEDED                  = BASE + 67;
440 
441     /** @hide */
442     public static final int STOP_LISTEN                             = BASE + 68;
443     /** @hide */
444     public static final int STOP_LISTEN_FAILED                      = BASE + 69;
445     /** @hide */
446     public static final int STOP_LISTEN_SUCCEEDED                   = BASE + 70;
447 
448     /** @hide */
449     public static final int SET_CHANNEL                             = BASE + 71;
450     /** @hide */
451     public static final int SET_CHANNEL_FAILED                      = BASE + 72;
452     /** @hide */
453     public static final int SET_CHANNEL_SUCCEEDED                   = BASE + 73;
454 
455 
456     /**
457      * Create a new WifiP2pManager instance. Applications use
458      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
459      * the standard {@link android.content.Context#WIFI_P2P_SERVICE Context.WIFI_P2P_SERVICE}.
460      * @param service the Binder interface
461      * @hide - hide this because it takes in a parameter of type IWifiP2pManager, which
462      * is a system private class.
463      */
WifiP2pManager(IWifiP2pManager service)464     public WifiP2pManager(IWifiP2pManager service) {
465         mService = service;
466     }
467 
468     /**
469      * Passed with {@link ActionListener#onFailure}.
470      * Indicates that the operation failed due to an internal error.
471      */
472     public static final int ERROR               = 0;
473 
474     /**
475      * Passed with {@link ActionListener#onFailure}.
476      * Indicates that the operation failed because p2p is unsupported on the device.
477      */
478     public static final int P2P_UNSUPPORTED     = 1;
479 
480     /**
481      * Passed with {@link ActionListener#onFailure}.
482      * Indicates that the operation failed because the framework is busy and
483      * unable to service the request
484      */
485     public static final int BUSY                = 2;
486 
487     /**
488      * Passed with {@link ActionListener#onFailure}.
489      * Indicates that the {@link #discoverServices} failed because no service
490      * requests are added. Use {@link #addServiceRequest} to add a service
491      * request.
492      */
493     public static final int NO_SERVICE_REQUESTS = 3;
494 
495     /** Interface for callback invocation when framework channel is lost */
496     public interface ChannelListener {
497         /**
498          * The channel to the framework has been disconnected.
499          * Application could try re-initializing using {@link #initialize}
500          */
onChannelDisconnected()501         public void onChannelDisconnected();
502     }
503 
504     /** Interface for callback invocation on an application action */
505     public interface ActionListener {
506         /** The operation succeeded */
onSuccess()507         public void onSuccess();
508         /**
509          * The operation failed
510          * @param reason The reason for failure could be one of {@link #P2P_UNSUPPORTED},
511          * {@link #ERROR} or {@link #BUSY}
512          */
onFailure(int reason)513         public void onFailure(int reason);
514     }
515 
516     /** Interface for callback invocation when peer list is available */
517     public interface PeerListListener {
518         /**
519          * The requested peer list is available
520          * @param peers List of available peers
521          */
onPeersAvailable(WifiP2pDeviceList peers)522         public void onPeersAvailable(WifiP2pDeviceList peers);
523     }
524 
525     /** Interface for callback invocation when connection info is available */
526     public interface ConnectionInfoListener {
527         /**
528          * The requested connection info is available
529          * @param info Wi-Fi p2p connection info
530          */
onConnectionInfoAvailable(WifiP2pInfo info)531         public void onConnectionInfoAvailable(WifiP2pInfo info);
532     }
533 
534     /** Interface for callback invocation when group info is available */
535     public interface GroupInfoListener {
536         /**
537          * The requested p2p group info is available
538          * @param group Wi-Fi p2p group info
539          */
onGroupInfoAvailable(WifiP2pGroup group)540         public void onGroupInfoAvailable(WifiP2pGroup group);
541     }
542 
543    /**
544     * Interface for callback invocation when service discovery response other than
545     * Upnp or Bonjour is received
546     */
547     public interface ServiceResponseListener {
548 
549         /**
550          * The requested service response is available.
551          *
552          * @param protocolType protocol type. currently only
553          * {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
554          * @param responseData service discovery response data based on the requested
555          *  service protocol type. The format depends on the service type.
556          * @param srcDevice source device.
557          */
onServiceAvailable(int protocolType, byte[] responseData, WifiP2pDevice srcDevice)558         public void onServiceAvailable(int protocolType,
559                 byte[] responseData, WifiP2pDevice srcDevice);
560     }
561 
562     /**
563      * Interface for callback invocation when Bonjour service discovery response
564      * is received
565      */
566     public interface DnsSdServiceResponseListener {
567 
568         /**
569          * The requested Bonjour service response is available.
570          *
571          * <p>This function is invoked when the device with the specified Bonjour
572          * registration type returned the instance name.
573          * @param instanceName instance name.<br>
574          *  e.g) "MyPrinter".
575          * @param registrationType <br>
576          * e.g) "_ipp._tcp.local."
577          * @param srcDevice source device.
578          */
onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice srcDevice)579         public void onDnsSdServiceAvailable(String instanceName,
580                 String registrationType, WifiP2pDevice srcDevice);
581 
582    }
583 
584     /**
585      * Interface for callback invocation when Bonjour TXT record is available
586      * for a service
587      */
588    public interface DnsSdTxtRecordListener {
589         /**
590          * The requested Bonjour service response is available.
591          *
592          * <p>This function is invoked when the device with the specified full
593          * service domain service returned TXT record.
594          *
595          * @param fullDomainName full domain name. <br>
596          * e.g) "MyPrinter._ipp._tcp.local.".
597          * @param txtRecordMap TXT record data as a map of key/value pairs
598          * @param srcDevice source device.
599          */
onDnsSdTxtRecordAvailable(String fullDomainName, Map<String, String> txtRecordMap, WifiP2pDevice srcDevice)600         public void onDnsSdTxtRecordAvailable(String fullDomainName,
601                 Map<String, String> txtRecordMap,
602                 WifiP2pDevice srcDevice);
603    }
604 
605     /**
606      * Interface for callback invocation when upnp service discovery response
607      * is received
608      * */
609     public interface UpnpServiceResponseListener {
610 
611         /**
612          * The requested upnp service response is available.
613          *
614          * <p>This function is invoked when the specified device or service is found.
615          *
616          * @param uniqueServiceNames The list of unique service names.<br>
617          * e.g) uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:
618          * MediaServer:1
619          * @param srcDevice source device.
620          */
onUpnpServiceAvailable(List<String> uniqueServiceNames, WifiP2pDevice srcDevice)621         public void onUpnpServiceAvailable(List<String> uniqueServiceNames,
622                 WifiP2pDevice srcDevice);
623     }
624 
625 
626     /** Interface for callback invocation when stored group info list is available {@hide}*/
627     public interface PersistentGroupInfoListener {
628         /**
629          * The requested stored p2p group info list is available
630          * @param groups Wi-Fi p2p group info list
631          */
onPersistentGroupInfoAvailable(WifiP2pGroupList groups)632         public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups);
633     }
634 
635     /**
636      * A channel that connects the application to the Wifi p2p framework.
637      * Most p2p operations require a Channel as an argument. An instance of Channel is obtained
638      * by doing a call on {@link #initialize}
639      */
640     public static class Channel {
Channel(Context context, Looper looper, ChannelListener l)641         Channel(Context context, Looper looper, ChannelListener l) {
642             mAsyncChannel = new AsyncChannel();
643             mHandler = new P2pHandler(looper);
644             mChannelListener = l;
645             mContext = context;
646         }
647         private final static int INVALID_LISTENER_KEY = 0;
648         private ChannelListener mChannelListener;
649         private ServiceResponseListener mServRspListener;
650         private DnsSdServiceResponseListener mDnsSdServRspListener;
651         private DnsSdTxtRecordListener mDnsSdTxtListener;
652         private UpnpServiceResponseListener mUpnpServRspListener;
653         private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>();
654         private Object mListenerMapLock = new Object();
655         private int mListenerKey = 0;
656 
657         private AsyncChannel mAsyncChannel;
658         private P2pHandler mHandler;
659         Context mContext;
660         class P2pHandler extends Handler {
P2pHandler(Looper looper)661             P2pHandler(Looper looper) {
662                 super(looper);
663             }
664 
665             @Override
handleMessage(Message message)666             public void handleMessage(Message message) {
667                 Object listener = getListener(message.arg2);
668                 switch (message.what) {
669                     case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
670                         if (mChannelListener != null) {
671                             mChannelListener.onChannelDisconnected();
672                             mChannelListener = null;
673                         }
674                         break;
675                     /* ActionListeners grouped together */
676                     case DISCOVER_PEERS_FAILED:
677                     case STOP_DISCOVERY_FAILED:
678                     case DISCOVER_SERVICES_FAILED:
679                     case CONNECT_FAILED:
680                     case CANCEL_CONNECT_FAILED:
681                     case CREATE_GROUP_FAILED:
682                     case REMOVE_GROUP_FAILED:
683                     case ADD_LOCAL_SERVICE_FAILED:
684                     case REMOVE_LOCAL_SERVICE_FAILED:
685                     case CLEAR_LOCAL_SERVICES_FAILED:
686                     case ADD_SERVICE_REQUEST_FAILED:
687                     case REMOVE_SERVICE_REQUEST_FAILED:
688                     case CLEAR_SERVICE_REQUESTS_FAILED:
689                     case SET_DEVICE_NAME_FAILED:
690                     case DELETE_PERSISTENT_GROUP_FAILED:
691                     case SET_WFD_INFO_FAILED:
692                     case START_WPS_FAILED:
693                     case START_LISTEN_FAILED:
694                     case STOP_LISTEN_FAILED:
695                     case SET_CHANNEL_FAILED:
696                         if (listener != null) {
697                             ((ActionListener) listener).onFailure(message.arg1);
698                         }
699                         break;
700                     /* ActionListeners grouped together */
701                     case DISCOVER_PEERS_SUCCEEDED:
702                     case STOP_DISCOVERY_SUCCEEDED:
703                     case DISCOVER_SERVICES_SUCCEEDED:
704                     case CONNECT_SUCCEEDED:
705                     case CANCEL_CONNECT_SUCCEEDED:
706                     case CREATE_GROUP_SUCCEEDED:
707                     case REMOVE_GROUP_SUCCEEDED:
708                     case ADD_LOCAL_SERVICE_SUCCEEDED:
709                     case REMOVE_LOCAL_SERVICE_SUCCEEDED:
710                     case CLEAR_LOCAL_SERVICES_SUCCEEDED:
711                     case ADD_SERVICE_REQUEST_SUCCEEDED:
712                     case REMOVE_SERVICE_REQUEST_SUCCEEDED:
713                     case CLEAR_SERVICE_REQUESTS_SUCCEEDED:
714                     case SET_DEVICE_NAME_SUCCEEDED:
715                     case DELETE_PERSISTENT_GROUP_SUCCEEDED:
716                     case SET_WFD_INFO_SUCCEEDED:
717                     case START_WPS_SUCCEEDED:
718                     case START_LISTEN_SUCCEEDED:
719                     case STOP_LISTEN_SUCCEEDED:
720                     case SET_CHANNEL_SUCCEEDED:
721                         if (listener != null) {
722                             ((ActionListener) listener).onSuccess();
723                         }
724                         break;
725                     case RESPONSE_PEERS:
726                         WifiP2pDeviceList peers = (WifiP2pDeviceList) message.obj;
727                         if (listener != null) {
728                             ((PeerListListener) listener).onPeersAvailable(peers);
729                         }
730                         break;
731                     case RESPONSE_CONNECTION_INFO:
732                         WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) message.obj;
733                         if (listener != null) {
734                             ((ConnectionInfoListener) listener).onConnectionInfoAvailable(wifiP2pInfo);
735                         }
736                         break;
737                     case RESPONSE_GROUP_INFO:
738                         WifiP2pGroup group = (WifiP2pGroup) message.obj;
739                         if (listener != null) {
740                             ((GroupInfoListener) listener).onGroupInfoAvailable(group);
741                         }
742                         break;
743                     case RESPONSE_SERVICE:
744                         WifiP2pServiceResponse resp = (WifiP2pServiceResponse) message.obj;
745                         handleServiceResponse(resp);
746                         break;
747                     case RESPONSE_PERSISTENT_GROUP_INFO:
748                         WifiP2pGroupList groups = (WifiP2pGroupList) message.obj;
749                         if (listener != null) {
750                             ((PersistentGroupInfoListener) listener).
751                                 onPersistentGroupInfoAvailable(groups);
752                         }
753                         break;
754                    default:
755                         Log.d(TAG, "Ignored " + message);
756                         break;
757                 }
758             }
759         }
760 
handleServiceResponse(WifiP2pServiceResponse resp)761         private void handleServiceResponse(WifiP2pServiceResponse resp) {
762             if (resp instanceof WifiP2pDnsSdServiceResponse) {
763                 handleDnsSdServiceResponse((WifiP2pDnsSdServiceResponse)resp);
764             } else if (resp instanceof WifiP2pUpnpServiceResponse) {
765                 if (mUpnpServRspListener != null) {
766                     handleUpnpServiceResponse((WifiP2pUpnpServiceResponse)resp);
767                 }
768             } else {
769                 if (mServRspListener != null) {
770                     mServRspListener.onServiceAvailable(resp.getServiceType(),
771                             resp.getRawData(), resp.getSrcDevice());
772                 }
773             }
774         }
775 
handleUpnpServiceResponse(WifiP2pUpnpServiceResponse resp)776         private void handleUpnpServiceResponse(WifiP2pUpnpServiceResponse resp) {
777             mUpnpServRspListener.onUpnpServiceAvailable(resp.getUniqueServiceNames(),
778                     resp.getSrcDevice());
779         }
780 
handleDnsSdServiceResponse(WifiP2pDnsSdServiceResponse resp)781         private void handleDnsSdServiceResponse(WifiP2pDnsSdServiceResponse resp) {
782             if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) {
783                 if (mDnsSdServRspListener != null) {
784                     mDnsSdServRspListener.onDnsSdServiceAvailable(
785                             resp.getInstanceName(),
786                             resp.getDnsQueryName(),
787                             resp.getSrcDevice());
788                 }
789             } else if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) {
790                 if (mDnsSdTxtListener != null) {
791                     mDnsSdTxtListener.onDnsSdTxtRecordAvailable(
792                             resp.getDnsQueryName(),
793                             resp.getTxtRecord(),
794                             resp.getSrcDevice());
795                 }
796             } else {
797                 Log.e(TAG, "Unhandled resp " + resp);
798             }
799         }
800 
putListener(Object listener)801         private int putListener(Object listener) {
802             if (listener == null) return INVALID_LISTENER_KEY;
803             int key;
804             synchronized (mListenerMapLock) {
805                 do {
806                     key = mListenerKey++;
807                 } while (key == INVALID_LISTENER_KEY);
808                 mListenerMap.put(key, listener);
809             }
810             return key;
811         }
812 
getListener(int key)813         private Object getListener(int key) {
814             if (key == INVALID_LISTENER_KEY) return null;
815             synchronized (mListenerMapLock) {
816                 return mListenerMap.remove(key);
817             }
818         }
819     }
820 
checkChannel(Channel c)821     private static void checkChannel(Channel c) {
822         if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
823     }
824 
checkServiceInfo(WifiP2pServiceInfo info)825     private static void checkServiceInfo(WifiP2pServiceInfo info) {
826         if (info == null) throw new IllegalArgumentException("service info is null");
827     }
828 
checkServiceRequest(WifiP2pServiceRequest req)829     private static void checkServiceRequest(WifiP2pServiceRequest req) {
830         if (req == null) throw new IllegalArgumentException("service request is null");
831     }
832 
checkP2pConfig(WifiP2pConfig c)833     private static void checkP2pConfig(WifiP2pConfig c) {
834         if (c == null) throw new IllegalArgumentException("config cannot be null");
835         if (TextUtils.isEmpty(c.deviceAddress)) {
836             throw new IllegalArgumentException("deviceAddress cannot be empty");
837         }
838     }
839 
840     /**
841      * Registers the application with the Wi-Fi framework. This function
842      * must be the first to be called before any p2p operations are performed.
843      *
844      * @param srcContext is the context of the source
845      * @param srcLooper is the Looper on which the callbacks are receivied
846      * @param listener for callback at loss of framework communication. Can be null.
847      * @return Channel instance that is necessary for performing any further p2p operations
848      */
initialize(Context srcContext, Looper srcLooper, ChannelListener listener)849     public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
850         Messenger messenger = getMessenger();
851         if (messenger == null) return null;
852 
853         Channel c = new Channel(srcContext, srcLooper, listener);
854         if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger)
855                 == AsyncChannel.STATUS_SUCCESSFUL) {
856             return c;
857         } else {
858             return null;
859         }
860     }
861 
862     /**
863      * Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers
864      * for the purpose of establishing a connection.
865      *
866      * <p> The function call immediately returns after sending a discovery request
867      * to the framework. The application is notified of a success or failure to initiate
868      * discovery through listener callbacks {@link ActionListener#onSuccess} or
869      * {@link ActionListener#onFailure}.
870      *
871      * <p> The discovery remains active until a connection is initiated or
872      * a p2p group is formed. Register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent to
873      * determine when the framework notifies of a change as peers are discovered.
874      *
875      * <p> Upon receiving a {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent, an application
876      * can request for the list of peers using {@link #requestPeers}.
877      *
878      * @param c is the channel created at {@link #initialize}
879      * @param listener for callbacks on success or failure. Can be null.
880      */
discoverPeers(Channel c, ActionListener listener)881     public void discoverPeers(Channel c, ActionListener listener) {
882         checkChannel(c);
883         c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener));
884     }
885 
886    /**
887      * Stop an ongoing peer discovery
888      *
889      * <p> The function call immediately returns after sending a stop request
890      * to the framework. The application is notified of a success or failure to initiate
891      * stop through listener callbacks {@link ActionListener#onSuccess} or
892      * {@link ActionListener#onFailure}.
893      *
894      * @param c is the channel created at {@link #initialize}
895      * @param listener for callbacks on success or failure. Can be null.
896      */
stopPeerDiscovery(Channel c, ActionListener listener)897     public void stopPeerDiscovery(Channel c, ActionListener listener) {
898         checkChannel(c);
899         c.mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, c.putListener(listener));
900     }
901 
902     /**
903      * Start a p2p connection to a device with the specified configuration.
904      *
905      * <p> The function call immediately returns after sending a connection request
906      * to the framework. The application is notified of a success or failure to initiate
907      * connect through listener callbacks {@link ActionListener#onSuccess} or
908      * {@link ActionListener#onFailure}.
909      *
910      * <p> Register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent to
911      * determine when the framework notifies of a change in connectivity.
912      *
913      * <p> If the current device is not part of a p2p group, a connect request initiates
914      * a group negotiation with the peer.
915      *
916      * <p> If the current device is part of an existing p2p group or has created
917      * a p2p group with {@link #createGroup}, an invitation to join the group is sent to
918      * the peer device.
919      *
920      * @param c is the channel created at {@link #initialize}
921      * @param config options as described in {@link WifiP2pConfig} class
922      * @param listener for callbacks on success or failure. Can be null.
923      */
connect(Channel c, WifiP2pConfig config, ActionListener listener)924     public void connect(Channel c, WifiP2pConfig config, ActionListener listener) {
925         checkChannel(c);
926         checkP2pConfig(config);
927         c.mAsyncChannel.sendMessage(CONNECT, 0, c.putListener(listener), config);
928     }
929 
930     /**
931      * Cancel any ongoing p2p group negotiation
932      *
933      * <p> The function call immediately returns after sending a connection cancellation request
934      * to the framework. The application is notified of a success or failure to initiate
935      * cancellation through listener callbacks {@link ActionListener#onSuccess} or
936      * {@link ActionListener#onFailure}.
937      *
938      * @param c is the channel created at {@link #initialize}
939      * @param listener for callbacks on success or failure. Can be null.
940      */
cancelConnect(Channel c, ActionListener listener)941     public void cancelConnect(Channel c, ActionListener listener) {
942         checkChannel(c);
943         c.mAsyncChannel.sendMessage(CANCEL_CONNECT, 0, c.putListener(listener));
944     }
945 
946     /**
947      * Create a p2p group with the current device as the group owner. This essentially creates
948      * an access point that can accept connections from legacy clients as well as other p2p
949      * devices.
950      *
951      * <p class="note"><strong>Note:</strong>
952      * This function would normally not be used unless the current device needs
953      * to form a p2p connection with a legacy client
954      *
955      * <p> The function call immediately returns after sending a group creation request
956      * to the framework. The application is notified of a success or failure to initiate
957      * group creation through listener callbacks {@link ActionListener#onSuccess} or
958      * {@link ActionListener#onFailure}.
959      *
960      * <p> Application can request for the group details with {@link #requestGroupInfo}.
961      *
962      * @param c is the channel created at {@link #initialize}
963      * @param listener for callbacks on success or failure. Can be null.
964      */
createGroup(Channel c, ActionListener listener)965     public void createGroup(Channel c, ActionListener listener) {
966         checkChannel(c);
967         c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.PERSISTENT_NET_ID,
968                 c.putListener(listener));
969     }
970 
971     /**
972      * Remove the current p2p group.
973      *
974      * <p> The function call immediately returns after sending a group removal request
975      * to the framework. The application is notified of a success or failure to initiate
976      * group removal through listener callbacks {@link ActionListener#onSuccess} or
977      * {@link ActionListener#onFailure}.
978      *
979      * @param c is the channel created at {@link #initialize}
980      * @param listener for callbacks on success or failure. Can be null.
981      */
removeGroup(Channel c, ActionListener listener)982     public void removeGroup(Channel c, ActionListener listener) {
983         checkChannel(c);
984         c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener));
985     }
986 
987     /** @hide */
listen(Channel c, boolean enable, ActionListener listener)988     public void listen(Channel c, boolean enable, ActionListener listener) {
989         checkChannel(c);
990         c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN,
991                 0, c.putListener(listener));
992     }
993 
994     /** @hide */
setWifiP2pChannels(Channel c, int lc, int oc, ActionListener listener)995     public void setWifiP2pChannels(Channel c, int lc, int oc, ActionListener listener) {
996         checkChannel(c);
997         Bundle p2pChannels = new Bundle();
998         p2pChannels.putInt("lc", lc);
999         p2pChannels.putInt("oc", oc);
1000         c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels);
1001     }
1002 
1003     /**
1004      * Start a Wi-Fi Protected Setup (WPS) session.
1005      *
1006      * <p> The function call immediately returns after sending a request to start a
1007      * WPS session. Currently, this is only valid if the current device is running
1008      * as a group owner to allow any new clients to join the group. The application
1009      * is notified of a success or failure to initiate WPS through listener callbacks
1010      * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}.
1011      * @hide
1012      */
startWps(Channel c, WpsInfo wps, ActionListener listener)1013     public void startWps(Channel c, WpsInfo wps, ActionListener listener) {
1014         checkChannel(c);
1015         c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), wps);
1016     }
1017 
1018     /**
1019      * Register a local service for service discovery. If a local service is registered,
1020      * the framework automatically responds to a service discovery request from a peer.
1021      *
1022      * <p> The function call immediately returns after sending a request to add a local
1023      * service to the framework. The application is notified of a success or failure to
1024      * add service through listener callbacks {@link ActionListener#onSuccess} or
1025      * {@link ActionListener#onFailure}.
1026      *
1027      * <p>The service information is set through {@link WifiP2pServiceInfo}.<br>
1028      * or its subclass calls  {@link WifiP2pUpnpServiceInfo#newInstance} or
1029      *  {@link WifiP2pDnsSdServiceInfo#newInstance} for a Upnp or Bonjour service
1030      * respectively
1031      *
1032      * <p>The service information can be cleared with calls to
1033      *  {@link #removeLocalService} or {@link #clearLocalServices}.
1034      *
1035      * @param c is the channel created at {@link #initialize}
1036      * @param servInfo is a local service information.
1037      * @param listener for callbacks on success or failure. Can be null.
1038      */
addLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener)1039     public void addLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener) {
1040         checkChannel(c);
1041         checkServiceInfo(servInfo);
1042         c.mAsyncChannel.sendMessage(ADD_LOCAL_SERVICE, 0, c.putListener(listener), servInfo);
1043     }
1044 
1045     /**
1046      * Remove a registered local service added with {@link #addLocalService}
1047      *
1048      * <p> The function call immediately returns after sending a request to remove a
1049      * local service to the framework. The application is notified of a success or failure to
1050      * add service through listener callbacks {@link ActionListener#onSuccess} or
1051      * {@link ActionListener#onFailure}.
1052      *
1053      * @param c is the channel created at {@link #initialize}
1054      * @param servInfo is the local service information.
1055      * @param listener for callbacks on success or failure. Can be null.
1056      */
removeLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener)1057     public void removeLocalService(Channel c, WifiP2pServiceInfo servInfo,
1058             ActionListener listener) {
1059         checkChannel(c);
1060         checkServiceInfo(servInfo);
1061         c.mAsyncChannel.sendMessage(REMOVE_LOCAL_SERVICE, 0, c.putListener(listener), servInfo);
1062     }
1063 
1064     /**
1065      * Clear all registered local services of service discovery.
1066      *
1067      * <p> The function call immediately returns after sending a request to clear all
1068      * local services to the framework. The application is notified of a success or failure to
1069      * add service through listener callbacks {@link ActionListener#onSuccess} or
1070      * {@link ActionListener#onFailure}.
1071      *
1072      * @param c is the channel created at {@link #initialize}
1073      * @param listener for callbacks on success or failure. Can be null.
1074      */
clearLocalServices(Channel c, ActionListener listener)1075     public void clearLocalServices(Channel c, ActionListener listener) {
1076         checkChannel(c);
1077         c.mAsyncChannel.sendMessage(CLEAR_LOCAL_SERVICES, 0, c.putListener(listener));
1078     }
1079 
1080     /**
1081      * Register a callback to be invoked on receiving service discovery response.
1082      * Used only for vendor specific protocol right now. For Bonjour or Upnp, use
1083      * {@link #setDnsSdResponseListeners} or {@link #setUpnpServiceResponseListener}
1084      * respectively.
1085      *
1086      * <p> see {@link #discoverServices} for the detail.
1087      *
1088      * @param c is the channel created at {@link #initialize}
1089      * @param listener for callbacks on receiving service discovery response.
1090      */
setServiceResponseListener(Channel c, ServiceResponseListener listener)1091     public void setServiceResponseListener(Channel c,
1092             ServiceResponseListener listener) {
1093         checkChannel(c);
1094         c.mServRspListener = listener;
1095     }
1096 
1097     /**
1098      * Register a callback to be invoked on receiving Bonjour service discovery
1099      * response.
1100      *
1101      * <p> see {@link #discoverServices} for the detail.
1102      *
1103      * @param c
1104      * @param servListener is for listening to a Bonjour service response
1105      * @param txtListener is for listening to a Bonjour TXT record response
1106      */
setDnsSdResponseListeners(Channel c, DnsSdServiceResponseListener servListener, DnsSdTxtRecordListener txtListener)1107     public void setDnsSdResponseListeners(Channel c,
1108             DnsSdServiceResponseListener servListener, DnsSdTxtRecordListener txtListener) {
1109         checkChannel(c);
1110         c.mDnsSdServRspListener = servListener;
1111         c.mDnsSdTxtListener = txtListener;
1112     }
1113 
1114     /**
1115      * Register a callback to be invoked on receiving upnp service discovery
1116      * response.
1117      *
1118      * <p> see {@link #discoverServices} for the detail.
1119      *
1120      * @param c is the channel created at {@link #initialize}
1121      * @param listener for callbacks on receiving service discovery response.
1122      */
setUpnpServiceResponseListener(Channel c, UpnpServiceResponseListener listener)1123     public void setUpnpServiceResponseListener(Channel c,
1124             UpnpServiceResponseListener listener) {
1125         checkChannel(c);
1126         c.mUpnpServRspListener = listener;
1127     }
1128 
1129     /**
1130      * Initiate service discovery. A discovery process involves scanning for
1131      * requested services for the purpose of establishing a connection to a peer
1132      * that supports an available service.
1133      *
1134      * <p> The function call immediately returns after sending a request to start service
1135      * discovery to the framework. The application is notified of a success or failure to initiate
1136      * discovery through listener callbacks {@link ActionListener#onSuccess} or
1137      * {@link ActionListener#onFailure}.
1138      *
1139      * <p> The services to be discovered are specified with calls to {@link #addServiceRequest}.
1140      *
1141      * <p>The application is notified of the response against the service discovery request
1142      * through listener callbacks registered by {@link #setServiceResponseListener} or
1143      * {@link #setDnsSdResponseListeners}, or {@link #setUpnpServiceResponseListener}.
1144      *
1145      * @param c is the channel created at {@link #initialize}
1146      * @param listener for callbacks on success or failure. Can be null.
1147      */
discoverServices(Channel c, ActionListener listener)1148     public void discoverServices(Channel c, ActionListener listener) {
1149         checkChannel(c);
1150         c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, c.putListener(listener));
1151     }
1152 
1153     /**
1154      * Add a service discovery request.
1155      *
1156      * <p> The function call immediately returns after sending a request to add service
1157      * discovery request to the framework. The application is notified of a success or failure to
1158      * add service through listener callbacks {@link ActionListener#onSuccess} or
1159      * {@link ActionListener#onFailure}.
1160      *
1161      * <p>After service discovery request is added, you can initiate service discovery by
1162      * {@link #discoverServices}.
1163      *
1164      * <p>The added service requests can be cleared with calls to
1165      * {@link #removeServiceRequest(Channel, WifiP2pServiceRequest, ActionListener)} or
1166      * {@link #clearServiceRequests(Channel, ActionListener)}.
1167      *
1168      * @param c is the channel created at {@link #initialize}
1169      * @param req is the service discovery request.
1170      * @param listener for callbacks on success or failure. Can be null.
1171      */
addServiceRequest(Channel c, WifiP2pServiceRequest req, ActionListener listener)1172     public void addServiceRequest(Channel c,
1173             WifiP2pServiceRequest req, ActionListener listener) {
1174         checkChannel(c);
1175         checkServiceRequest(req);
1176         c.mAsyncChannel.sendMessage(ADD_SERVICE_REQUEST, 0,
1177                 c.putListener(listener), req);
1178     }
1179 
1180     /**
1181      * Remove a specified service discovery request added with {@link #addServiceRequest}
1182      *
1183      * <p> The function call immediately returns after sending a request to remove service
1184      * discovery request to the framework. The application is notified of a success or failure to
1185      * add service through listener callbacks {@link ActionListener#onSuccess} or
1186      * {@link ActionListener#onFailure}.
1187      *
1188      * @param c is the channel created at {@link #initialize}
1189      * @param req is the service discovery request.
1190      * @param listener for callbacks on success or failure. Can be null.
1191      */
removeServiceRequest(Channel c, WifiP2pServiceRequest req, ActionListener listener)1192     public void removeServiceRequest(Channel c, WifiP2pServiceRequest req,
1193             ActionListener listener) {
1194         checkChannel(c);
1195         checkServiceRequest(req);
1196         c.mAsyncChannel.sendMessage(REMOVE_SERVICE_REQUEST, 0,
1197                 c.putListener(listener), req);
1198     }
1199 
1200     /**
1201      * Clear all registered service discovery requests.
1202      *
1203      * <p> The function call immediately returns after sending a request to clear all
1204      * service discovery requests to the framework. The application is notified of a success
1205      * or failure to add service through listener callbacks {@link ActionListener#onSuccess} or
1206      * {@link ActionListener#onFailure}.
1207      *
1208      * @param c is the channel created at {@link #initialize}
1209      * @param listener for callbacks on success or failure. Can be null.
1210      */
clearServiceRequests(Channel c, ActionListener listener)1211     public void clearServiceRequests(Channel c, ActionListener listener) {
1212         checkChannel(c);
1213         c.mAsyncChannel.sendMessage(CLEAR_SERVICE_REQUESTS,
1214                 0, c.putListener(listener));
1215     }
1216 
1217     /**
1218      * Request the current list of peers.
1219      *
1220      * @param c is the channel created at {@link #initialize}
1221      * @param listener for callback when peer list is available. Can be null.
1222      */
requestPeers(Channel c, PeerListListener listener)1223     public void requestPeers(Channel c, PeerListListener listener) {
1224         checkChannel(c);
1225         c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener));
1226     }
1227 
1228     /**
1229      * Request device connection info.
1230      *
1231      * @param c is the channel created at {@link #initialize}
1232      * @param listener for callback when connection info is available. Can be null.
1233      */
requestConnectionInfo(Channel c, ConnectionInfoListener listener)1234     public void requestConnectionInfo(Channel c, ConnectionInfoListener listener) {
1235         checkChannel(c);
1236         c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_INFO, 0, c.putListener(listener));
1237     }
1238 
1239     /**
1240      * Request p2p group info.
1241      *
1242      * @param c is the channel created at {@link #initialize}
1243      * @param listener for callback when group info is available. Can be null.
1244      */
requestGroupInfo(Channel c, GroupInfoListener listener)1245     public void requestGroupInfo(Channel c, GroupInfoListener listener) {
1246         checkChannel(c);
1247         c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO, 0, c.putListener(listener));
1248     }
1249 
1250     /**
1251      * Set p2p device name.
1252      * @hide
1253      * @param c is the channel created at {@link #initialize}
1254      * @param listener for callback when group info is available. Can be null.
1255      */
setDeviceName(Channel c, String devName, ActionListener listener)1256     public void setDeviceName(Channel c, String devName, ActionListener listener) {
1257         checkChannel(c);
1258         WifiP2pDevice d = new WifiP2pDevice();
1259         d.deviceName = devName;
1260         c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d);
1261     }
1262 
1263     /** @hide */
setWFDInfo( Channel c, WifiP2pWfdInfo wfdInfo, ActionListener listener)1264     public void setWFDInfo(
1265             Channel c, WifiP2pWfdInfo wfdInfo,
1266             ActionListener listener) {
1267         checkChannel(c);
1268         c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo);
1269     }
1270 
1271 
1272     /**
1273      * Delete a stored persistent group from the system settings.
1274      *
1275      * <p> The function call immediately returns after sending a persistent group removal request
1276      * to the framework. The application is notified of a success or failure to initiate
1277      * group removal through listener callbacks {@link ActionListener#onSuccess} or
1278      * {@link ActionListener#onFailure}.
1279      *
1280      * <p>The persistent p2p group list stored in the system can be obtained by
1281      * {@link #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener)} and
1282      *  a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}.
1283      *
1284      * @param c is the channel created at {@link #initialize}
1285      * @param netId he network id of the p2p group.
1286      * @param listener for callbacks on success or failure. Can be null.
1287      * @hide
1288      */
deletePersistentGroup(Channel c, int netId, ActionListener listener)1289     public void deletePersistentGroup(Channel c, int netId, ActionListener listener) {
1290         checkChannel(c);
1291         c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener));
1292     }
1293 
1294     /**
1295      * Request a list of all the persistent p2p groups stored in system.
1296      *
1297      * @param c is the channel created at {@link #initialize}
1298      * @param listener for callback when persistent group info list is available. Can be null.
1299      * @hide
1300      */
requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener)1301     public void requestPersistentGroupInfo(Channel c, PersistentGroupInfoListener listener) {
1302         checkChannel(c);
1303         c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener));
1304     }
1305 
1306     /** @hide */
1307     public static final int MIRACAST_DISABLED = 0;
1308     /** @hide */
1309     public static final int MIRACAST_SOURCE   = 1;
1310     /** @hide */
1311     public static final int MIRACAST_SINK     = 2;
1312     /** Internal use only @hide */
setMiracastMode(int mode)1313     public void setMiracastMode(int mode) {
1314         try {
1315             mService.setMiracastMode(mode);
1316         } catch(RemoteException e) {
1317            // ignore
1318         }
1319     }
1320 
1321     /**
1322      * Get a reference to WifiP2pService handler. This is used to establish
1323      * an AsyncChannel communication with WifiService
1324      *
1325      * @return Messenger pointing to the WifiP2pService handler
1326      * @hide
1327      */
getMessenger()1328     public Messenger getMessenger() {
1329         try {
1330             return mService.getMessenger();
1331         } catch (RemoteException e) {
1332             return null;
1333         }
1334     }
1335 
1336 }
1337