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