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