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