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