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.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.RequiresPermission; 23 import android.annotation.SdkConstant; 24 import android.annotation.SdkConstant.SdkConstantType; 25 import android.annotation.SystemApi; 26 import android.annotation.SystemService; 27 import android.compat.annotation.UnsupportedAppUsage; 28 import android.content.Context; 29 import android.net.NetworkInfo; 30 import android.net.wifi.WpsInfo; 31 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo; 32 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse; 33 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; 34 import android.net.wifi.p2p.nsd.WifiP2pServiceRequest; 35 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse; 36 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo; 37 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse; 38 import android.os.Binder; 39 import android.os.Build; 40 import android.os.Bundle; 41 import android.os.Handler; 42 import android.os.Looper; 43 import android.os.Message; 44 import android.os.Messenger; 45 import android.os.RemoteException; 46 import android.text.TextUtils; 47 import android.util.CloseGuard; 48 import android.util.Log; 49 50 import com.android.internal.util.AsyncChannel; 51 import com.android.internal.util.Protocol; 52 53 import java.lang.annotation.Retention; 54 import java.lang.annotation.RetentionPolicy; 55 import java.lang.ref.Reference; 56 import java.util.HashMap; 57 import java.util.List; 58 import java.util.Map; 59 60 /** 61 * This class provides the API for managing Wi-Fi peer-to-peer connectivity. This lets an 62 * application discover available peers, setup connection to peers and query for the list of peers. 63 * When a p2p connection is formed over wifi, the device continues to maintain the uplink 64 * connection over mobile or any other available network for internet connectivity on the device. 65 * 66 * <p> The API is asynchronous and responses to requests from an application are on listener 67 * callbacks provided by the application. The application needs to do an initialization with 68 * {@link #initialize} before doing any p2p operation. 69 * 70 * <p> Most application calls need a {@link ActionListener} instance for receiving callbacks 71 * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}. Action callbacks 72 * indicate whether the initiation of the action was a success or a failure. 73 * Upon failure, the reason of failure can be one of {@link #ERROR}, {@link #P2P_UNSUPPORTED} 74 * or {@link #BUSY}. 75 * 76 * <p> An application can initiate discovery of peers with {@link #discoverPeers}. An initiated 77 * discovery request from an application stays active until the device starts connecting to a peer 78 * ,forms a p2p group or there is an explicit {@link #stopPeerDiscovery}. 79 * Applications can listen to {@link #WIFI_P2P_DISCOVERY_CHANGED_ACTION} to know if a peer-to-peer 80 * discovery is running or stopped. Additionally, {@link #WIFI_P2P_PEERS_CHANGED_ACTION} indicates 81 * if the peer list has changed. 82 * 83 * <p> When an application needs to fetch the current list of peers, it can request the list 84 * of peers with {@link #requestPeers}. When the peer list is available 85 * {@link PeerListListener#onPeersAvailable} is called with the device list. 86 * 87 * <p> An application can initiate a connection request to a peer through {@link #connect}. See 88 * {@link WifiP2pConfig} for details on setting up the configuration. For communication with legacy 89 * Wi-Fi devices that do not support p2p, an app can create a group using {@link #createGroup} 90 * which creates an access point whose details can be fetched with {@link #requestGroupInfo}. 91 * 92 * <p> After a successful group formation through {@link #createGroup} or through {@link #connect}, 93 * use {@link #requestConnectionInfo} to fetch the connection details. The connection info 94 * {@link WifiP2pInfo} contains the address of the group owner 95 * {@link WifiP2pInfo#groupOwnerAddress} and a flag {@link WifiP2pInfo#isGroupOwner} to indicate 96 * if the current device is a p2p group owner. A p2p client can thus communicate with 97 * the p2p group owner through a socket connection. If the current device is the p2p group owner, 98 * {@link WifiP2pInfo#groupOwnerAddress} is anonymized unless the caller holds the 99 * {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} permission. 100 * 101 * <p> With peer discovery using {@link #discoverPeers}, an application discovers the neighboring 102 * peers, but has no good way to figure out which peer to establish a connection with. For example, 103 * if a game application is interested in finding all the neighboring peers that are also running 104 * the same game, it has no way to find out until after the connection is setup. Pre-association 105 * service discovery is meant to address this issue of filtering the peers based on the running 106 * services. 107 * 108 * <p>With pre-association service discovery, an application can advertise a service for a 109 * application on a peer device prior to a connection setup between the devices. 110 * Currently, DNS based service discovery (Bonjour) and Upnp are the higher layer protocols 111 * supported. Get Bonjour resources at dns-sd.org and Upnp resources at upnp.org 112 * As an example, a video application can discover a Upnp capable media renderer 113 * prior to setting up a Wi-fi p2p connection with the device. 114 * 115 * <p> An application can advertise a Upnp or a Bonjour service with a call to 116 * {@link #addLocalService}. After a local service is added, 117 * the framework automatically responds to a peer application discovering the service prior 118 * to establishing a p2p connection. A call to {@link #removeLocalService} removes a local 119 * service and {@link #clearLocalServices} can be used to clear all local services. 120 * 121 * <p> An application that is looking for peer devices that support certain services 122 * can do so with a call to {@link #discoverServices}. Prior to initiating the discovery, 123 * application can add service discovery request with a call to {@link #addServiceRequest}, 124 * remove a service discovery request with a call to {@link #removeServiceRequest} or clear 125 * all requests with a call to {@link #clearServiceRequests}. When no service requests remain, 126 * a previously running service discovery will stop. 127 * 128 * The application is notified of a result of service discovery request through listener callbacks 129 * set through {@link #setDnsSdResponseListeners} for Bonjour or 130 * {@link #setUpnpServiceResponseListener} for Upnp. 131 * 132 * <p class="note"><strong>Note:</strong> 133 * Registering an application handler with {@link #initialize} requires the permissions 134 * {@link android.Manifest.permission#ACCESS_WIFI_STATE} and 135 * {@link android.Manifest.permission#CHANGE_WIFI_STATE} to perform any further peer-to-peer 136 * operations. 137 * 138 * {@see WifiP2pConfig} 139 * {@see WifiP2pInfo} 140 * {@see WifiP2pGroup} 141 * {@see WifiP2pDevice} 142 * {@see WifiP2pDeviceList} 143 * {@see android.net.wifi.WpsInfo} 144 */ 145 @SystemService(Context.WIFI_P2P_SERVICE) 146 public class WifiP2pManager { 147 private static final String TAG = "WifiP2pManager"; 148 /** 149 * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. An 150 * extra {@link #EXTRA_WIFI_STATE} provides the state information as int. 151 * 152 * @see #EXTRA_WIFI_STATE 153 */ 154 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 155 public static final String WIFI_P2P_STATE_CHANGED_ACTION = 156 "android.net.wifi.p2p.STATE_CHANGED"; 157 158 /** 159 * The lookup key for an int that indicates whether Wi-Fi p2p is enabled or disabled. 160 * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}. 161 * 162 * @see #WIFI_P2P_STATE_DISABLED 163 * @see #WIFI_P2P_STATE_ENABLED 164 */ 165 public static final String EXTRA_WIFI_STATE = "wifi_p2p_state"; 166 167 /** @hide */ 168 @IntDef({ 169 WIFI_P2P_STATE_DISABLED, 170 WIFI_P2P_STATE_ENABLED}) 171 @Retention(RetentionPolicy.SOURCE) 172 public @interface WifiP2pState { 173 } 174 175 /** 176 * Wi-Fi p2p is disabled. 177 * 178 * @see #WIFI_P2P_STATE_CHANGED_ACTION 179 */ 180 public static final int WIFI_P2P_STATE_DISABLED = 1; 181 182 /** 183 * Wi-Fi p2p is enabled. 184 * 185 * @see #WIFI_P2P_STATE_CHANGED_ACTION 186 */ 187 public static final int WIFI_P2P_STATE_ENABLED = 2; 188 189 /** 190 * Broadcast intent action indicating that the state of Wi-Fi p2p connectivity 191 * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in 192 * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides 193 * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides 194 * the details of the group and may contain a {@code null}. 195 * 196 * All of these permissions are required to receive this broadcast: 197 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and 198 * {@link android.Manifest.permission#ACCESS_WIFI_STATE} 199 * 200 * @see #EXTRA_WIFI_P2P_INFO 201 * @see #EXTRA_NETWORK_INFO 202 * @see #EXTRA_WIFI_P2P_GROUP 203 */ 204 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 205 public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = 206 "android.net.wifi.p2p.CONNECTION_STATE_CHANGE"; 207 208 /** 209 * The lookup key for a {@link android.net.wifi.p2p.WifiP2pInfo} object 210 * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. 211 */ 212 public static final String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo"; 213 214 /** 215 * The lookup key for a {@link android.net.NetworkInfo} object associated with the 216 * p2p network. Retrieve with 217 * {@link android.content.Intent#getParcelableExtra(String)}. 218 */ 219 public static final String EXTRA_NETWORK_INFO = "networkInfo"; 220 221 /** 222 * The lookup key for a {@link android.net.wifi.p2p.WifiP2pGroup} object 223 * associated with the p2p network. Retrieve with 224 * {@link android.content.Intent#getParcelableExtra(String)}. 225 */ 226 public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo"; 227 228 /** 229 * Broadcast intent action indicating that the available peer list has changed. This 230 * can be sent as a result of peers being found, lost or updated. 231 * 232 * All of these permissions are required to receive this broadcast: 233 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and 234 * {@link android.Manifest.permission#ACCESS_WIFI_STATE} 235 * 236 * <p> An extra {@link #EXTRA_P2P_DEVICE_LIST} provides the full list of 237 * current peers. The full list of peers can also be obtained any time with 238 * {@link #requestPeers}. 239 * 240 * @see #EXTRA_P2P_DEVICE_LIST 241 */ 242 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 243 public static final String WIFI_P2P_PEERS_CHANGED_ACTION = 244 "android.net.wifi.p2p.PEERS_CHANGED"; 245 246 /** 247 * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDeviceList} object representing 248 * the new peer list when {@link #WIFI_P2P_PEERS_CHANGED_ACTION} broadcast is sent. 249 * 250 * <p>Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. 251 */ 252 public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList"; 253 254 /** 255 * Broadcast intent action indicating that peer discovery has either started or stopped. 256 * One extra {@link #EXTRA_DISCOVERY_STATE} indicates whether discovery has started 257 * or stopped. 258 * 259 * <p>Note that discovery will be stopped during a connection setup. If the application tries 260 * to re-initiate discovery during this time, it can fail. 261 */ 262 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 263 public static final String WIFI_P2P_DISCOVERY_CHANGED_ACTION = 264 "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE"; 265 266 /** 267 * The lookup key for an int that indicates whether p2p discovery has started or stopped. 268 * Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}. 269 * 270 * @see #WIFI_P2P_DISCOVERY_STARTED 271 * @see #WIFI_P2P_DISCOVERY_STOPPED 272 */ 273 public static final String EXTRA_DISCOVERY_STATE = "discoveryState"; 274 275 /** @hide */ 276 @IntDef({ 277 WIFI_P2P_DISCOVERY_STOPPED, 278 WIFI_P2P_DISCOVERY_STARTED}) 279 @Retention(RetentionPolicy.SOURCE) 280 public @interface WifiP2pDiscoveryState { 281 } 282 283 /** 284 * p2p discovery has stopped 285 * 286 * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION 287 */ 288 public static final int WIFI_P2P_DISCOVERY_STOPPED = 1; 289 290 /** 291 * p2p discovery has started 292 * 293 * @see #WIFI_P2P_DISCOVERY_CHANGED_ACTION 294 */ 295 public static final int WIFI_P2P_DISCOVERY_STARTED = 2; 296 297 /** 298 * Broadcast intent action indicating that this device details have changed. 299 * 300 * <p> An extra {@link #EXTRA_WIFI_P2P_DEVICE} provides this device details. 301 * The valid device details can also be obtained with 302 * {@link #requestDeviceInfo(Channel, DeviceInfoListener)} when p2p is enabled. 303 * To get information notifications on P2P getting enabled refers 304 * {@link #WIFI_P2P_STATE_ENABLED}. 305 * 306 * <p> The {@link #EXTRA_WIFI_P2P_DEVICE} extra contains an anonymized version of the device's 307 * MAC address. Callers holding the {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} 308 * permission can use {@link #requestDeviceInfo} to obtain the actual MAC address of this 309 * device. 310 * 311 * All of these permissions are required to receive this broadcast: 312 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and 313 * {@link android.Manifest.permission#ACCESS_WIFI_STATE} 314 * 315 * @see #EXTRA_WIFI_P2P_DEVICE 316 */ 317 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 318 public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION = 319 "android.net.wifi.p2p.THIS_DEVICE_CHANGED"; 320 321 /** 322 * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDevice} object 323 * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. 324 */ 325 public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice"; 326 327 /** 328 * Broadcast intent action indicating that remembered persistent groups have changed. 329 * 330 * You can <em>not</em> receive this through components declared 331 * in manifests, only by explicitly registering for it with 332 * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver, 333 * android.content.IntentFilter) Context.registerReceiver()}. 334 * 335 * @hide 336 */ 337 @SystemApi 338 public static final String ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED = 339 "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED"; 340 341 /** 342 * The lookup key for a handover message returned by the WifiP2pService. 343 * @hide 344 */ 345 public static final String EXTRA_HANDOVER_MESSAGE = 346 "android.net.wifi.p2p.EXTRA_HANDOVER_MESSAGE"; 347 348 /** 349 * The lookup key for a calling package name from WifiP2pManager 350 * @hide 351 */ 352 public static final String CALLING_PACKAGE = 353 "android.net.wifi.p2p.CALLING_PACKAGE"; 354 355 /** 356 * The lookup key for a calling feature id from WifiP2pManager 357 * @hide 358 */ 359 public static final String CALLING_FEATURE_ID = 360 "android.net.wifi.p2p.CALLING_FEATURE_ID"; 361 362 /** 363 * The lookup key for a calling package binder from WifiP2pManager 364 * @hide 365 */ 366 public static final String CALLING_BINDER = 367 "android.net.wifi.p2p.CALLING_BINDER"; 368 369 IWifiP2pManager mService; 370 371 private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER; 372 373 /** @hide */ 374 public static final int DISCOVER_PEERS = BASE + 1; 375 /** @hide */ 376 public static final int DISCOVER_PEERS_FAILED = BASE + 2; 377 /** @hide */ 378 public static final int DISCOVER_PEERS_SUCCEEDED = BASE + 3; 379 380 /** @hide */ 381 public static final int STOP_DISCOVERY = BASE + 4; 382 /** @hide */ 383 public static final int STOP_DISCOVERY_FAILED = BASE + 5; 384 /** @hide */ 385 public static final int STOP_DISCOVERY_SUCCEEDED = BASE + 6; 386 387 /** @hide */ 388 public static final int CONNECT = BASE + 7; 389 /** @hide */ 390 public static final int CONNECT_FAILED = BASE + 8; 391 /** @hide */ 392 public static final int CONNECT_SUCCEEDED = BASE + 9; 393 394 /** @hide */ 395 public static final int CANCEL_CONNECT = BASE + 10; 396 /** @hide */ 397 public static final int CANCEL_CONNECT_FAILED = BASE + 11; 398 /** @hide */ 399 public static final int CANCEL_CONNECT_SUCCEEDED = BASE + 12; 400 401 /** @hide */ 402 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 403 public static final int CREATE_GROUP = BASE + 13; 404 /** @hide */ 405 public static final int CREATE_GROUP_FAILED = BASE + 14; 406 /** @hide */ 407 public static final int CREATE_GROUP_SUCCEEDED = BASE + 15; 408 409 /** @hide */ 410 public static final int REMOVE_GROUP = BASE + 16; 411 /** @hide */ 412 public static final int REMOVE_GROUP_FAILED = BASE + 17; 413 /** @hide */ 414 public static final int REMOVE_GROUP_SUCCEEDED = BASE + 18; 415 416 /** @hide */ 417 public static final int REQUEST_PEERS = BASE + 19; 418 /** @hide */ 419 public static final int RESPONSE_PEERS = BASE + 20; 420 421 /** @hide */ 422 public static final int REQUEST_CONNECTION_INFO = BASE + 21; 423 /** @hide */ 424 public static final int RESPONSE_CONNECTION_INFO = BASE + 22; 425 426 /** @hide */ 427 public static final int REQUEST_GROUP_INFO = BASE + 23; 428 /** @hide */ 429 public static final int RESPONSE_GROUP_INFO = BASE + 24; 430 431 /** @hide */ 432 public static final int ADD_LOCAL_SERVICE = BASE + 28; 433 /** @hide */ 434 public static final int ADD_LOCAL_SERVICE_FAILED = BASE + 29; 435 /** @hide */ 436 public static final int ADD_LOCAL_SERVICE_SUCCEEDED = BASE + 30; 437 438 /** @hide */ 439 public static final int REMOVE_LOCAL_SERVICE = BASE + 31; 440 /** @hide */ 441 public static final int REMOVE_LOCAL_SERVICE_FAILED = BASE + 32; 442 /** @hide */ 443 public static final int REMOVE_LOCAL_SERVICE_SUCCEEDED = BASE + 33; 444 445 /** @hide */ 446 public static final int CLEAR_LOCAL_SERVICES = BASE + 34; 447 /** @hide */ 448 public static final int CLEAR_LOCAL_SERVICES_FAILED = BASE + 35; 449 /** @hide */ 450 public static final int CLEAR_LOCAL_SERVICES_SUCCEEDED = BASE + 36; 451 452 /** @hide */ 453 public static final int ADD_SERVICE_REQUEST = BASE + 37; 454 /** @hide */ 455 public static final int ADD_SERVICE_REQUEST_FAILED = BASE + 38; 456 /** @hide */ 457 public static final int ADD_SERVICE_REQUEST_SUCCEEDED = BASE + 39; 458 459 /** @hide */ 460 public static final int REMOVE_SERVICE_REQUEST = BASE + 40; 461 /** @hide */ 462 public static final int REMOVE_SERVICE_REQUEST_FAILED = BASE + 41; 463 /** @hide */ 464 public static final int REMOVE_SERVICE_REQUEST_SUCCEEDED = BASE + 42; 465 466 /** @hide */ 467 public static final int CLEAR_SERVICE_REQUESTS = BASE + 43; 468 /** @hide */ 469 public static final int CLEAR_SERVICE_REQUESTS_FAILED = BASE + 44; 470 /** @hide */ 471 public static final int CLEAR_SERVICE_REQUESTS_SUCCEEDED = BASE + 45; 472 473 /** @hide */ 474 public static final int DISCOVER_SERVICES = BASE + 46; 475 /** @hide */ 476 public static final int DISCOVER_SERVICES_FAILED = BASE + 47; 477 /** @hide */ 478 public static final int DISCOVER_SERVICES_SUCCEEDED = BASE + 48; 479 480 /** @hide */ 481 public static final int PING = BASE + 49; 482 483 /** @hide */ 484 public static final int RESPONSE_SERVICE = BASE + 50; 485 486 /** @hide */ 487 public static final int SET_DEVICE_NAME = BASE + 51; 488 /** @hide */ 489 public static final int SET_DEVICE_NAME_FAILED = BASE + 52; 490 /** @hide */ 491 public static final int SET_DEVICE_NAME_SUCCEEDED = BASE + 53; 492 493 /** @hide */ 494 public static final int DELETE_PERSISTENT_GROUP = BASE + 54; 495 /** @hide */ 496 public static final int DELETE_PERSISTENT_GROUP_FAILED = BASE + 55; 497 /** @hide */ 498 public static final int DELETE_PERSISTENT_GROUP_SUCCEEDED = BASE + 56; 499 500 /** @hide */ 501 public static final int REQUEST_PERSISTENT_GROUP_INFO = BASE + 57; 502 /** @hide */ 503 public static final int RESPONSE_PERSISTENT_GROUP_INFO = BASE + 58; 504 505 /** @hide */ 506 public static final int SET_WFD_INFO = BASE + 59; 507 /** @hide */ 508 public static final int SET_WFD_INFO_FAILED = BASE + 60; 509 /** @hide */ 510 public static final int SET_WFD_INFO_SUCCEEDED = BASE + 61; 511 512 /** @hide */ 513 public static final int START_WPS = BASE + 62; 514 /** @hide */ 515 public static final int START_WPS_FAILED = BASE + 63; 516 /** @hide */ 517 public static final int START_WPS_SUCCEEDED = BASE + 64; 518 519 /** @hide */ 520 public static final int START_LISTEN = BASE + 65; 521 /** @hide */ 522 public static final int START_LISTEN_FAILED = BASE + 66; 523 /** @hide */ 524 public static final int START_LISTEN_SUCCEEDED = BASE + 67; 525 526 /** @hide */ 527 public static final int STOP_LISTEN = BASE + 68; 528 /** @hide */ 529 public static final int STOP_LISTEN_FAILED = BASE + 69; 530 /** @hide */ 531 public static final int STOP_LISTEN_SUCCEEDED = BASE + 70; 532 533 /** @hide */ 534 public static final int SET_CHANNEL = BASE + 71; 535 /** @hide */ 536 public static final int SET_CHANNEL_FAILED = BASE + 72; 537 /** @hide */ 538 public static final int SET_CHANNEL_SUCCEEDED = BASE + 73; 539 540 /** @hide */ 541 public static final int GET_HANDOVER_REQUEST = BASE + 75; 542 /** @hide */ 543 public static final int GET_HANDOVER_SELECT = BASE + 76; 544 /** @hide */ 545 public static final int RESPONSE_GET_HANDOVER_MESSAGE = BASE + 77; 546 /** @hide */ 547 public static final int INITIATOR_REPORT_NFC_HANDOVER = BASE + 78; 548 /** @hide */ 549 public static final int RESPONDER_REPORT_NFC_HANDOVER = BASE + 79; 550 /** @hide */ 551 public static final int REPORT_NFC_HANDOVER_SUCCEEDED = BASE + 80; 552 /** @hide */ 553 public static final int REPORT_NFC_HANDOVER_FAILED = BASE + 81; 554 555 /** @hide */ 556 public static final int FACTORY_RESET = BASE + 82; 557 /** @hide */ 558 public static final int FACTORY_RESET_FAILED = BASE + 83; 559 /** @hide */ 560 public static final int FACTORY_RESET_SUCCEEDED = BASE + 84; 561 562 /** @hide */ 563 public static final int REQUEST_ONGOING_PEER_CONFIG = BASE + 85; 564 /** @hide */ 565 public static final int RESPONSE_ONGOING_PEER_CONFIG = BASE + 86; 566 /** @hide */ 567 public static final int SET_ONGOING_PEER_CONFIG = BASE + 87; 568 /** @hide */ 569 public static final int SET_ONGOING_PEER_CONFIG_FAILED = BASE + 88; 570 /** @hide */ 571 public static final int SET_ONGOING_PEER_CONFIG_SUCCEEDED = BASE + 89; 572 573 /** @hide */ 574 public static final int REQUEST_P2P_STATE = BASE + 90; 575 /** @hide */ 576 public static final int RESPONSE_P2P_STATE = BASE + 91; 577 578 /** @hide */ 579 public static final int REQUEST_DISCOVERY_STATE = BASE + 92; 580 /** @hide */ 581 public static final int RESPONSE_DISCOVERY_STATE = BASE + 93; 582 583 /** @hide */ 584 public static final int REQUEST_NETWORK_INFO = BASE + 94; 585 /** @hide */ 586 public static final int RESPONSE_NETWORK_INFO = BASE + 95; 587 588 /** @hide */ 589 public static final int UPDATE_CHANNEL_INFO = BASE + 96; 590 591 /** @hide */ 592 public static final int REQUEST_DEVICE_INFO = BASE + 97; 593 /** @hide */ 594 public static final int RESPONSE_DEVICE_INFO = BASE + 98; 595 596 /** 597 * Create a new WifiP2pManager instance. Applications use 598 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve 599 * the standard {@link android.content.Context#WIFI_P2P_SERVICE Context.WIFI_P2P_SERVICE}. 600 * @param service the Binder interface 601 * @hide - hide this because it takes in a parameter of type IWifiP2pManager, which 602 * is a system private class. 603 */ 604 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) WifiP2pManager(IWifiP2pManager service)605 public WifiP2pManager(IWifiP2pManager service) { 606 mService = service; 607 } 608 609 /** 610 * Passed with {@link ActionListener#onFailure}. 611 * Indicates that the operation failed due to an internal error. 612 */ 613 public static final int ERROR = 0; 614 615 /** 616 * Passed with {@link ActionListener#onFailure}. 617 * Indicates that the operation failed because p2p is unsupported on the device. 618 */ 619 public static final int P2P_UNSUPPORTED = 1; 620 621 /** 622 * Passed with {@link ActionListener#onFailure}. 623 * Indicates that the operation failed because the framework is busy and 624 * unable to service the request 625 */ 626 public static final int BUSY = 2; 627 628 /** 629 * Passed with {@link ActionListener#onFailure}. 630 * Indicates that the {@link #discoverServices} failed because no service 631 * requests are added. Use {@link #addServiceRequest} to add a service 632 * request. 633 */ 634 public static final int NO_SERVICE_REQUESTS = 3; 635 636 /** Interface for callback invocation when framework channel is lost */ 637 public interface ChannelListener { 638 /** 639 * The channel to the framework has been disconnected. 640 * Application could try re-initializing using {@link #initialize} 641 */ onChannelDisconnected()642 public void onChannelDisconnected(); 643 } 644 645 /** Interface for callback invocation on an application action */ 646 public interface ActionListener { 647 /** The operation succeeded */ onSuccess()648 public void onSuccess(); 649 /** 650 * The operation failed 651 * @param reason The reason for failure could be one of {@link #P2P_UNSUPPORTED}, 652 * {@link #ERROR} or {@link #BUSY} 653 */ onFailure(int reason)654 public void onFailure(int reason); 655 } 656 657 /** Interface for callback invocation when peer list is available */ 658 public interface PeerListListener { 659 /** 660 * The requested peer list is available 661 * @param peers List of available peers 662 */ onPeersAvailable(WifiP2pDeviceList peers)663 public void onPeersAvailable(WifiP2pDeviceList peers); 664 } 665 666 /** Interface for callback invocation when connection info is available */ 667 public interface ConnectionInfoListener { 668 /** 669 * The requested connection info is available 670 * @param info Wi-Fi p2p connection info 671 */ onConnectionInfoAvailable(WifiP2pInfo info)672 public void onConnectionInfoAvailable(WifiP2pInfo info); 673 } 674 675 /** Interface for callback invocation when group info is available */ 676 public interface GroupInfoListener { 677 /** 678 * The requested p2p group info is available 679 * @param group Wi-Fi p2p group info 680 */ onGroupInfoAvailable(WifiP2pGroup group)681 public void onGroupInfoAvailable(WifiP2pGroup group); 682 } 683 684 /** 685 * Interface for callback invocation when service discovery response other than 686 * Upnp or Bonjour is received 687 */ 688 public interface ServiceResponseListener { 689 690 /** 691 * The requested service response is available. 692 * 693 * @param protocolType protocol type. currently only 694 * {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}. 695 * @param responseData service discovery response data based on the requested 696 * service protocol type. The format depends on the service type. 697 * @param srcDevice source device. 698 */ onServiceAvailable(int protocolType, byte[] responseData, WifiP2pDevice srcDevice)699 public void onServiceAvailable(int protocolType, 700 byte[] responseData, WifiP2pDevice srcDevice); 701 } 702 703 /** 704 * Interface for callback invocation when Bonjour service discovery response 705 * is received 706 */ 707 public interface DnsSdServiceResponseListener { 708 709 /** 710 * The requested Bonjour service response is available. 711 * 712 * <p>This function is invoked when the device with the specified Bonjour 713 * registration type returned the instance name. 714 * @param instanceName instance name.<br> 715 * e.g) "MyPrinter". 716 * @param registrationType <br> 717 * e.g) "_ipp._tcp.local." 718 * @param srcDevice source device. 719 */ onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice srcDevice)720 public void onDnsSdServiceAvailable(String instanceName, 721 String registrationType, WifiP2pDevice srcDevice); 722 723 } 724 725 /** 726 * Interface for callback invocation when Bonjour TXT record is available 727 * for a service 728 */ 729 public interface DnsSdTxtRecordListener { 730 /** 731 * The requested Bonjour service response is available. 732 * 733 * <p>This function is invoked when the device with the specified full 734 * service domain service returned TXT record. 735 * 736 * @param fullDomainName full domain name. <br> 737 * e.g) "MyPrinter._ipp._tcp.local.". 738 * @param txtRecordMap TXT record data as a map of key/value pairs 739 * @param srcDevice source device. 740 */ onDnsSdTxtRecordAvailable(String fullDomainName, Map<String, String> txtRecordMap, WifiP2pDevice srcDevice)741 public void onDnsSdTxtRecordAvailable(String fullDomainName, 742 Map<String, String> txtRecordMap, 743 WifiP2pDevice srcDevice); 744 } 745 746 /** 747 * Interface for callback invocation when upnp service discovery response 748 * is received 749 * */ 750 public interface UpnpServiceResponseListener { 751 752 /** 753 * The requested upnp service response is available. 754 * 755 * <p>This function is invoked when the specified device or service is found. 756 * 757 * @param uniqueServiceNames The list of unique service names.<br> 758 * e.g) uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device: 759 * MediaServer:1 760 * @param srcDevice source device. 761 */ onUpnpServiceAvailable(List<String> uniqueServiceNames, WifiP2pDevice srcDevice)762 public void onUpnpServiceAvailable(List<String> uniqueServiceNames, 763 WifiP2pDevice srcDevice); 764 } 765 766 767 /** 768 * Interface for callback invocation when stored group info list is available 769 * 770 * @hide 771 */ 772 @SystemApi 773 public interface PersistentGroupInfoListener { 774 /** 775 * The requested stored p2p group info list is available 776 * @param groups Wi-Fi p2p group info list 777 */ onPersistentGroupInfoAvailable(@onNull WifiP2pGroupList groups)778 void onPersistentGroupInfoAvailable(@NonNull WifiP2pGroupList groups); 779 } 780 781 /** 782 * Interface for callback invocation when Handover Request or Select Message is available 783 * @hide 784 */ 785 public interface HandoverMessageListener { onHandoverMessageAvailable(String handoverMessage)786 public void onHandoverMessageAvailable(String handoverMessage); 787 } 788 789 /** Interface for callback invocation when p2p state is available 790 * in response to {@link #requestP2pState}. 791 */ 792 public interface P2pStateListener { 793 /** 794 * The requested p2p state is available. 795 * @param state Wi-Fi p2p state 796 * @see #WIFI_P2P_STATE_DISABLED 797 * @see #WIFI_P2P_STATE_ENABLED 798 */ onP2pStateAvailable(@ifiP2pState int state)799 void onP2pStateAvailable(@WifiP2pState int state); 800 } 801 802 /** Interface for callback invocation when p2p state is available 803 * in response to {@link #requestDiscoveryState}. 804 */ 805 public interface DiscoveryStateListener { 806 /** 807 * The requested p2p discovery state is available. 808 * @param state Wi-Fi p2p discovery state 809 * @see #WIFI_P2P_DISCOVERY_STARTED 810 * @see #WIFI_P2P_DISCOVERY_STOPPED 811 */ onDiscoveryStateAvailable(@ifiP2pDiscoveryState int state)812 void onDiscoveryStateAvailable(@WifiP2pDiscoveryState int state); 813 } 814 815 /** Interface for callback invocation when {@link android.net.NetworkInfo} is available 816 * in response to {@link #requestNetworkInfo}. 817 */ 818 public interface NetworkInfoListener { 819 /** 820 * The requested {@link android.net.NetworkInfo} is available 821 * @param networkInfo Wi-Fi p2p {@link android.net.NetworkInfo} 822 */ onNetworkInfoAvailable(@onNull NetworkInfo networkInfo)823 void onNetworkInfoAvailable(@NonNull NetworkInfo networkInfo); 824 } 825 826 /** 827 * Interface for callback invocation when ongoing peer info is available 828 * @hide 829 */ 830 public interface OngoingPeerInfoListener { 831 /** 832 * The requested ongoing WifiP2pConfig is available 833 * @param peerConfig WifiP2pConfig for current connecting session 834 */ onOngoingPeerAvailable(WifiP2pConfig peerConfig)835 void onOngoingPeerAvailable(WifiP2pConfig peerConfig); 836 } 837 838 /** Interface for callback invocation when {@link android.net.wifi.p2p.WifiP2pDevice} 839 * is available in response to {@link #requestDeviceInfo(Channel, DeviceInfoListener)}. 840 */ 841 public interface DeviceInfoListener { 842 /** 843 * The requested {@link android.net.wifi.p2p.WifiP2pDevice} is available. 844 * @param wifiP2pDevice Wi-Fi p2p {@link android.net.wifi.p2p.WifiP2pDevice} 845 */ onDeviceInfoAvailable(@ullable WifiP2pDevice wifiP2pDevice)846 void onDeviceInfoAvailable(@Nullable WifiP2pDevice wifiP2pDevice); 847 } 848 849 /** 850 * A channel that connects the application to the Wifi p2p framework. 851 * Most p2p operations require a Channel as an argument. An instance of Channel is obtained 852 * by doing a call on {@link #initialize} 853 */ 854 public static class Channel implements AutoCloseable { 855 /** @hide */ Channel(Context context, Looper looper, ChannelListener l, Binder binder, WifiP2pManager p2pManager)856 public Channel(Context context, Looper looper, ChannelListener l, Binder binder, 857 WifiP2pManager p2pManager) { 858 mAsyncChannel = new AsyncChannel(); 859 mHandler = new P2pHandler(looper); 860 mChannelListener = l; 861 mContext = context; 862 mBinder = binder; 863 mP2pManager = p2pManager; 864 865 mCloseGuard.open("close"); 866 } 867 private final static int INVALID_LISTENER_KEY = 0; 868 private final WifiP2pManager mP2pManager; 869 private ChannelListener mChannelListener; 870 private ServiceResponseListener mServRspListener; 871 private DnsSdServiceResponseListener mDnsSdServRspListener; 872 private DnsSdTxtRecordListener mDnsSdTxtListener; 873 private UpnpServiceResponseListener mUpnpServRspListener; 874 private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>(); 875 private final Object mListenerMapLock = new Object(); 876 private int mListenerKey = 0; 877 878 private final CloseGuard mCloseGuard = new CloseGuard(); 879 880 /** 881 * Close the current P2P connection and indicate to the P2P service that connections 882 * created by the app can be removed. 883 */ close()884 public void close() { 885 if (mP2pManager == null) { 886 Log.w(TAG, "Channel.close(): Null mP2pManager!?"); 887 } else { 888 try { 889 mP2pManager.mService.close(mBinder); 890 } catch (RemoteException e) { 891 throw e.rethrowFromSystemServer(); 892 } 893 } 894 895 mAsyncChannel.disconnect(); 896 mCloseGuard.close(); 897 Reference.reachabilityFence(this); 898 } 899 900 /** @hide */ 901 @Override finalize()902 protected void finalize() throws Throwable { 903 try { 904 if (mCloseGuard != null) { 905 mCloseGuard.warnIfOpen(); 906 } 907 908 close(); 909 } finally { 910 super.finalize(); 911 } 912 } 913 914 /* package */ final Binder mBinder; 915 916 @UnsupportedAppUsage 917 private AsyncChannel mAsyncChannel; 918 private P2pHandler mHandler; 919 Context mContext; 920 class P2pHandler extends Handler { P2pHandler(Looper looper)921 P2pHandler(Looper looper) { 922 super(looper); 923 } 924 925 @Override handleMessage(Message message)926 public void handleMessage(Message message) { 927 Object listener = getListener(message.arg2); 928 switch (message.what) { 929 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 930 if (mChannelListener != null) { 931 mChannelListener.onChannelDisconnected(); 932 mChannelListener = null; 933 } 934 break; 935 /* ActionListeners grouped together */ 936 case DISCOVER_PEERS_FAILED: 937 case STOP_DISCOVERY_FAILED: 938 case DISCOVER_SERVICES_FAILED: 939 case CONNECT_FAILED: 940 case CANCEL_CONNECT_FAILED: 941 case CREATE_GROUP_FAILED: 942 case REMOVE_GROUP_FAILED: 943 case ADD_LOCAL_SERVICE_FAILED: 944 case REMOVE_LOCAL_SERVICE_FAILED: 945 case CLEAR_LOCAL_SERVICES_FAILED: 946 case ADD_SERVICE_REQUEST_FAILED: 947 case REMOVE_SERVICE_REQUEST_FAILED: 948 case CLEAR_SERVICE_REQUESTS_FAILED: 949 case SET_DEVICE_NAME_FAILED: 950 case DELETE_PERSISTENT_GROUP_FAILED: 951 case SET_WFD_INFO_FAILED: 952 case START_WPS_FAILED: 953 case START_LISTEN_FAILED: 954 case STOP_LISTEN_FAILED: 955 case SET_CHANNEL_FAILED: 956 case REPORT_NFC_HANDOVER_FAILED: 957 case FACTORY_RESET_FAILED: 958 case SET_ONGOING_PEER_CONFIG_FAILED: 959 if (listener != null) { 960 ((ActionListener) listener).onFailure(message.arg1); 961 } 962 break; 963 /* ActionListeners grouped together */ 964 case DISCOVER_PEERS_SUCCEEDED: 965 case STOP_DISCOVERY_SUCCEEDED: 966 case DISCOVER_SERVICES_SUCCEEDED: 967 case CONNECT_SUCCEEDED: 968 case CANCEL_CONNECT_SUCCEEDED: 969 case CREATE_GROUP_SUCCEEDED: 970 case REMOVE_GROUP_SUCCEEDED: 971 case ADD_LOCAL_SERVICE_SUCCEEDED: 972 case REMOVE_LOCAL_SERVICE_SUCCEEDED: 973 case CLEAR_LOCAL_SERVICES_SUCCEEDED: 974 case ADD_SERVICE_REQUEST_SUCCEEDED: 975 case REMOVE_SERVICE_REQUEST_SUCCEEDED: 976 case CLEAR_SERVICE_REQUESTS_SUCCEEDED: 977 case SET_DEVICE_NAME_SUCCEEDED: 978 case DELETE_PERSISTENT_GROUP_SUCCEEDED: 979 case SET_WFD_INFO_SUCCEEDED: 980 case START_WPS_SUCCEEDED: 981 case START_LISTEN_SUCCEEDED: 982 case STOP_LISTEN_SUCCEEDED: 983 case SET_CHANNEL_SUCCEEDED: 984 case REPORT_NFC_HANDOVER_SUCCEEDED: 985 case FACTORY_RESET_SUCCEEDED: 986 case SET_ONGOING_PEER_CONFIG_SUCCEEDED: 987 if (listener != null) { 988 ((ActionListener) listener).onSuccess(); 989 } 990 break; 991 case RESPONSE_PEERS: 992 WifiP2pDeviceList peers = (WifiP2pDeviceList) message.obj; 993 if (listener != null) { 994 ((PeerListListener) listener).onPeersAvailable(peers); 995 } 996 break; 997 case RESPONSE_CONNECTION_INFO: 998 WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) message.obj; 999 if (listener != null) { 1000 ((ConnectionInfoListener) listener).onConnectionInfoAvailable(wifiP2pInfo); 1001 } 1002 break; 1003 case RESPONSE_GROUP_INFO: 1004 WifiP2pGroup group = (WifiP2pGroup) message.obj; 1005 if (listener != null) { 1006 ((GroupInfoListener) listener).onGroupInfoAvailable(group); 1007 } 1008 break; 1009 case RESPONSE_SERVICE: 1010 WifiP2pServiceResponse resp = (WifiP2pServiceResponse) message.obj; 1011 handleServiceResponse(resp); 1012 break; 1013 case RESPONSE_PERSISTENT_GROUP_INFO: 1014 WifiP2pGroupList groups = (WifiP2pGroupList) message.obj; 1015 if (listener != null) { 1016 ((PersistentGroupInfoListener) listener). 1017 onPersistentGroupInfoAvailable(groups); 1018 } 1019 break; 1020 case RESPONSE_GET_HANDOVER_MESSAGE: 1021 Bundle handoverBundle = (Bundle) message.obj; 1022 if (listener != null) { 1023 String handoverMessage = handoverBundle != null 1024 ? handoverBundle.getString(EXTRA_HANDOVER_MESSAGE) 1025 : null; 1026 ((HandoverMessageListener) listener) 1027 .onHandoverMessageAvailable(handoverMessage); 1028 } 1029 break; 1030 case RESPONSE_ONGOING_PEER_CONFIG: 1031 WifiP2pConfig peerConfig = (WifiP2pConfig) message.obj; 1032 if (listener != null) { 1033 ((OngoingPeerInfoListener) listener) 1034 .onOngoingPeerAvailable(peerConfig); 1035 } 1036 break; 1037 case RESPONSE_P2P_STATE: 1038 if (listener != null) { 1039 ((P2pStateListener) listener) 1040 .onP2pStateAvailable(message.arg1); 1041 } 1042 break; 1043 case RESPONSE_DISCOVERY_STATE: 1044 if (listener != null) { 1045 ((DiscoveryStateListener) listener) 1046 .onDiscoveryStateAvailable(message.arg1); 1047 } 1048 break; 1049 case RESPONSE_NETWORK_INFO: 1050 if (listener != null) { 1051 ((NetworkInfoListener) listener) 1052 .onNetworkInfoAvailable((NetworkInfo) message.obj); 1053 } 1054 break; 1055 case RESPONSE_DEVICE_INFO: 1056 if (listener != null) { 1057 ((DeviceInfoListener) listener) 1058 .onDeviceInfoAvailable((WifiP2pDevice) message.obj); 1059 } 1060 break; 1061 default: 1062 Log.d(TAG, "Ignored " + message); 1063 break; 1064 } 1065 } 1066 } 1067 handleServiceResponse(WifiP2pServiceResponse resp)1068 private void handleServiceResponse(WifiP2pServiceResponse resp) { 1069 if (resp instanceof WifiP2pDnsSdServiceResponse) { 1070 handleDnsSdServiceResponse((WifiP2pDnsSdServiceResponse)resp); 1071 } else if (resp instanceof WifiP2pUpnpServiceResponse) { 1072 if (mUpnpServRspListener != null) { 1073 handleUpnpServiceResponse((WifiP2pUpnpServiceResponse)resp); 1074 } 1075 } else { 1076 if (mServRspListener != null) { 1077 mServRspListener.onServiceAvailable(resp.getServiceType(), 1078 resp.getRawData(), resp.getSrcDevice()); 1079 } 1080 } 1081 } 1082 handleUpnpServiceResponse(WifiP2pUpnpServiceResponse resp)1083 private void handleUpnpServiceResponse(WifiP2pUpnpServiceResponse resp) { 1084 mUpnpServRspListener.onUpnpServiceAvailable(resp.getUniqueServiceNames(), 1085 resp.getSrcDevice()); 1086 } 1087 handleDnsSdServiceResponse(WifiP2pDnsSdServiceResponse resp)1088 private void handleDnsSdServiceResponse(WifiP2pDnsSdServiceResponse resp) { 1089 if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_PTR) { 1090 if (mDnsSdServRspListener != null) { 1091 mDnsSdServRspListener.onDnsSdServiceAvailable( 1092 resp.getInstanceName(), 1093 resp.getDnsQueryName(), 1094 resp.getSrcDevice()); 1095 } 1096 } else if (resp.getDnsType() == WifiP2pDnsSdServiceInfo.DNS_TYPE_TXT) { 1097 if (mDnsSdTxtListener != null) { 1098 mDnsSdTxtListener.onDnsSdTxtRecordAvailable( 1099 resp.getDnsQueryName(), 1100 resp.getTxtRecord(), 1101 resp.getSrcDevice()); 1102 } 1103 } else { 1104 Log.e(TAG, "Unhandled resp " + resp); 1105 } 1106 } 1107 1108 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) putListener(Object listener)1109 private int putListener(Object listener) { 1110 if (listener == null) return INVALID_LISTENER_KEY; 1111 int key; 1112 synchronized (mListenerMapLock) { 1113 do { 1114 key = mListenerKey++; 1115 } while (key == INVALID_LISTENER_KEY); 1116 mListenerMap.put(key, listener); 1117 } 1118 return key; 1119 } 1120 getListener(int key)1121 private Object getListener(int key) { 1122 if (key == INVALID_LISTENER_KEY) return null; 1123 synchronized (mListenerMapLock) { 1124 return mListenerMap.remove(key); 1125 } 1126 } 1127 } 1128 checkChannel(Channel c)1129 private static void checkChannel(Channel c) { 1130 if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); 1131 } 1132 checkServiceInfo(WifiP2pServiceInfo info)1133 private static void checkServiceInfo(WifiP2pServiceInfo info) { 1134 if (info == null) throw new IllegalArgumentException("service info is null"); 1135 } 1136 checkServiceRequest(WifiP2pServiceRequest req)1137 private static void checkServiceRequest(WifiP2pServiceRequest req) { 1138 if (req == null) throw new IllegalArgumentException("service request is null"); 1139 } 1140 checkP2pConfig(WifiP2pConfig c)1141 private static void checkP2pConfig(WifiP2pConfig c) { 1142 if (c == null) throw new IllegalArgumentException("config cannot be null"); 1143 if (TextUtils.isEmpty(c.deviceAddress)) { 1144 throw new IllegalArgumentException("deviceAddress cannot be empty"); 1145 } 1146 } 1147 1148 /** 1149 * Registers the application with the Wi-Fi framework. This function 1150 * must be the first to be called before any p2p operations are performed. 1151 * 1152 * @param srcContext is the context of the source 1153 * @param srcLooper is the Looper on which the callbacks are receivied 1154 * @param listener for callback at loss of framework communication. Can be null. 1155 * @return Channel instance that is necessary for performing any further p2p operations 1156 */ initialize(Context srcContext, Looper srcLooper, ChannelListener listener)1157 public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) { 1158 Binder binder = new Binder(); 1159 Channel channel = initializeChannel(srcContext, srcLooper, listener, 1160 getMessenger(binder, srcContext.getOpPackageName()), binder); 1161 return channel; 1162 } 1163 1164 /** 1165 * Registers the application with the Wi-Fi framework. Enables system-only functionality. 1166 * @hide 1167 */ initializeInternal(Context srcContext, Looper srcLooper, ChannelListener listener)1168 public Channel initializeInternal(Context srcContext, Looper srcLooper, 1169 ChannelListener listener) { 1170 return initializeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(), 1171 null); 1172 } 1173 initializeChannel(Context srcContext, Looper srcLooper, ChannelListener listener, Messenger messenger, Binder binder)1174 private Channel initializeChannel(Context srcContext, Looper srcLooper, 1175 ChannelListener listener, Messenger messenger, Binder binder) { 1176 if (messenger == null) return null; 1177 1178 Channel c = new Channel(srcContext, srcLooper, listener, binder, this); 1179 if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger) 1180 == AsyncChannel.STATUS_SUCCESSFUL) { 1181 Bundle bundle = new Bundle(); 1182 bundle.putString(CALLING_PACKAGE, c.mContext.getOpPackageName()); 1183 bundle.putString(CALLING_FEATURE_ID, c.mContext.getAttributionTag()); 1184 bundle.putBinder(CALLING_BINDER, binder); 1185 c.mAsyncChannel.sendMessage(UPDATE_CHANNEL_INFO, 0, 1186 c.putListener(null), bundle); 1187 return c; 1188 } else { 1189 c.close(); 1190 return null; 1191 } 1192 } 1193 1194 /** 1195 * Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers 1196 * for the purpose of establishing a connection. 1197 * 1198 * <p> The function call immediately returns after sending a discovery request 1199 * to the framework. The application is notified of a success or failure to initiate 1200 * discovery through listener callbacks {@link ActionListener#onSuccess} or 1201 * {@link ActionListener#onFailure}. 1202 * 1203 * <p> The discovery remains active until a connection is initiated or 1204 * a p2p group is formed. Register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent to 1205 * determine when the framework notifies of a change as peers are discovered. 1206 * 1207 * <p> Upon receiving a {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent, an application 1208 * can request for the list of peers using {@link #requestPeers}. 1209 * 1210 * @param c is the channel created at {@link #initialize} 1211 * @param listener for callbacks on success or failure. Can be null. 1212 */ 1213 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) discoverPeers(Channel c, ActionListener listener)1214 public void discoverPeers(Channel c, ActionListener listener) { 1215 checkChannel(c); 1216 c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener)); 1217 } 1218 1219 /** 1220 * Stop an ongoing peer discovery 1221 * 1222 * <p> The function call immediately returns after sending a stop request 1223 * to the framework. The application is notified of a success or failure to initiate 1224 * stop through listener callbacks {@link ActionListener#onSuccess} or 1225 * {@link ActionListener#onFailure}. 1226 * 1227 * @param c is the channel created at {@link #initialize} 1228 * @param listener for callbacks on success or failure. Can be null. 1229 */ stopPeerDiscovery(Channel c, ActionListener listener)1230 public void stopPeerDiscovery(Channel c, ActionListener listener) { 1231 checkChannel(c); 1232 c.mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, c.putListener(listener)); 1233 } 1234 1235 /** 1236 * Start a p2p connection to a device with the specified configuration. 1237 * 1238 * <p> The function call immediately returns after sending a connection request 1239 * to the framework. The application is notified of a success or failure to initiate 1240 * connect through listener callbacks {@link ActionListener#onSuccess} or 1241 * {@link ActionListener#onFailure}. 1242 * 1243 * <p> Register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent to 1244 * determine when the framework notifies of a change in connectivity. 1245 * 1246 * <p> If the current device is not part of a p2p group, a connect request initiates 1247 * a group negotiation with the peer. 1248 * 1249 * <p> If the current device is part of an existing p2p group or has created 1250 * a p2p group with {@link #createGroup}, an invitation to join the group is sent to 1251 * the peer device. 1252 * 1253 * @param c is the channel created at {@link #initialize} 1254 * @param config options as described in {@link WifiP2pConfig} class 1255 * @param listener for callbacks on success or failure. Can be null. 1256 */ 1257 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) connect(Channel c, WifiP2pConfig config, ActionListener listener)1258 public void connect(Channel c, WifiP2pConfig config, ActionListener listener) { 1259 checkChannel(c); 1260 checkP2pConfig(config); 1261 c.mAsyncChannel.sendMessage(CONNECT, 0, c.putListener(listener), config); 1262 } 1263 1264 /** 1265 * Cancel any ongoing p2p group negotiation 1266 * 1267 * <p> The function call immediately returns after sending a connection cancellation request 1268 * to the framework. The application is notified of a success or failure to initiate 1269 * cancellation through listener callbacks {@link ActionListener#onSuccess} or 1270 * {@link ActionListener#onFailure}. 1271 * 1272 * @param c is the channel created at {@link #initialize} 1273 * @param listener for callbacks on success or failure. Can be null. 1274 */ cancelConnect(Channel c, ActionListener listener)1275 public void cancelConnect(Channel c, ActionListener listener) { 1276 checkChannel(c); 1277 c.mAsyncChannel.sendMessage(CANCEL_CONNECT, 0, c.putListener(listener)); 1278 } 1279 1280 /** 1281 * Create a p2p group with the current device as the group owner. This essentially creates 1282 * an access point that can accept connections from legacy clients as well as other p2p 1283 * devices. 1284 * 1285 * <p class="note"><strong>Note:</strong> 1286 * This function would normally not be used unless the current device needs 1287 * to form a p2p connection with a legacy client 1288 * 1289 * <p> The function call immediately returns after sending a group creation request 1290 * to the framework. The application is notified of a success or failure to initiate 1291 * group creation through listener callbacks {@link ActionListener#onSuccess} or 1292 * {@link ActionListener#onFailure}. 1293 * 1294 * <p> Application can request for the group details with {@link #requestGroupInfo}. 1295 * 1296 * @param c is the channel created at {@link #initialize} 1297 * @param listener for callbacks on success or failure. Can be null. 1298 */ 1299 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) createGroup(Channel c, ActionListener listener)1300 public void createGroup(Channel c, ActionListener listener) { 1301 checkChannel(c); 1302 c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PERSISTENT, 1303 c.putListener(listener)); 1304 } 1305 1306 /** 1307 * Create a p2p group with the current device as the group owner. This essentially creates 1308 * an access point that can accept connections from legacy clients as well as other p2p 1309 * devices. 1310 * 1311 * <p> An app should use {@link WifiP2pConfig.Builder} to build the configuration 1312 * for a group. 1313 * 1314 * <p class="note"><strong>Note:</strong> 1315 * This function would normally not be used unless the current device needs 1316 * to form a p2p group as a Group Owner and allow peers to join it as either 1317 * Group Clients or legacy Wi-Fi STAs. 1318 * 1319 * <p> The function call immediately returns after sending a group creation request 1320 * to the framework. The application is notified of a success or failure to initiate 1321 * group creation through listener callbacks {@link ActionListener#onSuccess} or 1322 * {@link ActionListener#onFailure}. 1323 * 1324 * <p> Application can request for the group details with {@link #requestGroupInfo}. 1325 * 1326 * @param c is the channel created at {@link #initialize}. 1327 * @param config the configuration of a p2p group. 1328 * @param listener for callbacks on success or failure. Can be null. 1329 */ 1330 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) createGroup(@onNull Channel c, @Nullable WifiP2pConfig config, @Nullable ActionListener listener)1331 public void createGroup(@NonNull Channel c, 1332 @Nullable WifiP2pConfig config, 1333 @Nullable ActionListener listener) { 1334 checkChannel(c); 1335 c.mAsyncChannel.sendMessage(CREATE_GROUP, 0, 1336 c.putListener(listener), config); 1337 } 1338 1339 /** 1340 * Remove the current p2p group. 1341 * 1342 * <p> The function call immediately returns after sending a group removal request 1343 * to the framework. The application is notified of a success or failure to initiate 1344 * group removal through listener callbacks {@link ActionListener#onSuccess} or 1345 * {@link ActionListener#onFailure}. 1346 * 1347 * @param c is the channel created at {@link #initialize} 1348 * @param listener for callbacks on success or failure. Can be null. 1349 */ removeGroup(Channel c, ActionListener listener)1350 public void removeGroup(Channel c, ActionListener listener) { 1351 checkChannel(c); 1352 c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener)); 1353 } 1354 1355 /** 1356 * Force p2p to enter listen state 1357 * 1358 * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)} 1359 * @param listener for callbacks on success or failure. Can be null. 1360 * 1361 * @hide 1362 */ 1363 @SystemApi 1364 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) startListening(@onNull Channel c, @Nullable ActionListener listener)1365 public void startListening(@NonNull Channel c, @Nullable ActionListener listener) { 1366 checkChannel(c); 1367 c.mAsyncChannel.sendMessage(START_LISTEN, 0, c.putListener(listener)); 1368 } 1369 1370 /** 1371 * Force p2p to exit listen state 1372 * 1373 * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)} 1374 * @param listener for callbacks on success or failure. Can be null. 1375 * 1376 * @hide 1377 */ 1378 @SystemApi 1379 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) stopListening(@onNull Channel c, @Nullable ActionListener listener)1380 public void stopListening(@NonNull Channel c, @Nullable ActionListener listener) { 1381 checkChannel(c); 1382 c.mAsyncChannel.sendMessage(STOP_LISTEN, 0, c.putListener(listener)); 1383 } 1384 1385 /** 1386 * Set P2P listening and operating channel. 1387 * 1388 * @param c is the channel created at {@link #initialize} 1389 * @param listeningChannel the listening channel's Wifi channel number. e.g. 1, 6, 11. 1390 * @param operatingChannel the operating channel's Wifi channel number. e.g. 1, 6, 11. 1391 * @param listener for callbacks on success or failure. Can be null. 1392 * 1393 * @hide 1394 */ 1395 @SystemApi 1396 @RequiresPermission(anyOf = { 1397 android.Manifest.permission.NETWORK_SETTINGS, 1398 android.Manifest.permission.NETWORK_STACK, 1399 android.Manifest.permission.OVERRIDE_WIFI_CONFIG 1400 }) setWifiP2pChannels(@onNull Channel c, int listeningChannel, int operatingChannel, @Nullable ActionListener listener)1401 public void setWifiP2pChannels(@NonNull Channel c, int listeningChannel, int operatingChannel, 1402 @Nullable ActionListener listener) { 1403 checkChannel(c); 1404 Bundle p2pChannels = new Bundle(); 1405 p2pChannels.putInt("lc", listeningChannel); 1406 p2pChannels.putInt("oc", operatingChannel); 1407 c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels); 1408 } 1409 1410 /** 1411 * Start a Wi-Fi Protected Setup (WPS) session. 1412 * 1413 * <p> The function call immediately returns after sending a request to start a 1414 * WPS session. Currently, this is only valid if the current device is running 1415 * as a group owner to allow any new clients to join the group. The application 1416 * is notified of a success or failure to initiate WPS through listener callbacks 1417 * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}. 1418 * @hide 1419 */ 1420 @UnsupportedAppUsage(trackingBug = 185141982) startWps(Channel c, WpsInfo wps, ActionListener listener)1421 public void startWps(Channel c, WpsInfo wps, ActionListener listener) { 1422 checkChannel(c); 1423 c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), wps); 1424 } 1425 1426 /** 1427 * Register a local service for service discovery. If a local service is registered, 1428 * the framework automatically responds to a service discovery request from a peer. 1429 * 1430 * <p> The function call immediately returns after sending a request to add a local 1431 * service to the framework. The application is notified of a success or failure to 1432 * add service through listener callbacks {@link ActionListener#onSuccess} or 1433 * {@link ActionListener#onFailure}. 1434 * 1435 * <p>The service information is set through {@link WifiP2pServiceInfo}.<br> 1436 * or its subclass calls {@link WifiP2pUpnpServiceInfo#newInstance} or 1437 * {@link WifiP2pDnsSdServiceInfo#newInstance} for a Upnp or Bonjour service 1438 * respectively 1439 * 1440 * <p>The service information can be cleared with calls to 1441 * {@link #removeLocalService} or {@link #clearLocalServices}. 1442 * 1443 * @param c is the channel created at {@link #initialize} 1444 * @param servInfo is a local service information. 1445 * @param listener for callbacks on success or failure. Can be null. 1446 */ 1447 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) addLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener)1448 public void addLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener) { 1449 checkChannel(c); 1450 checkServiceInfo(servInfo); 1451 c.mAsyncChannel.sendMessage(ADD_LOCAL_SERVICE, 0, c.putListener(listener), servInfo); 1452 } 1453 1454 /** 1455 * Remove a registered local service added with {@link #addLocalService} 1456 * 1457 * <p> The function call immediately returns after sending a request to remove a 1458 * local service to the framework. The application is notified of a success or failure to 1459 * add service through listener callbacks {@link ActionListener#onSuccess} or 1460 * {@link ActionListener#onFailure}. 1461 * 1462 * @param c is the channel created at {@link #initialize} 1463 * @param servInfo is the local service information. 1464 * @param listener for callbacks on success or failure. Can be null. 1465 */ removeLocalService(Channel c, WifiP2pServiceInfo servInfo, ActionListener listener)1466 public void removeLocalService(Channel c, WifiP2pServiceInfo servInfo, 1467 ActionListener listener) { 1468 checkChannel(c); 1469 checkServiceInfo(servInfo); 1470 c.mAsyncChannel.sendMessage(REMOVE_LOCAL_SERVICE, 0, c.putListener(listener), servInfo); 1471 } 1472 1473 /** 1474 * Clear all registered local services of service discovery. 1475 * 1476 * <p> The function call immediately returns after sending a request to clear all 1477 * local services to the framework. The application is notified of a success or failure to 1478 * add service through listener callbacks {@link ActionListener#onSuccess} or 1479 * {@link ActionListener#onFailure}. 1480 * 1481 * @param c is the channel created at {@link #initialize} 1482 * @param listener for callbacks on success or failure. Can be null. 1483 */ clearLocalServices(Channel c, ActionListener listener)1484 public void clearLocalServices(Channel c, ActionListener listener) { 1485 checkChannel(c); 1486 c.mAsyncChannel.sendMessage(CLEAR_LOCAL_SERVICES, 0, c.putListener(listener)); 1487 } 1488 1489 /** 1490 * Register a callback to be invoked on receiving service discovery response. 1491 * Used only for vendor specific protocol right now. For Bonjour or Upnp, use 1492 * {@link #setDnsSdResponseListeners} or {@link #setUpnpServiceResponseListener} 1493 * respectively. 1494 * 1495 * <p> see {@link #discoverServices} for the detail. 1496 * 1497 * @param c is the channel created at {@link #initialize} 1498 * @param listener for callbacks on receiving service discovery response. 1499 */ setServiceResponseListener(Channel c, ServiceResponseListener listener)1500 public void setServiceResponseListener(Channel c, 1501 ServiceResponseListener listener) { 1502 checkChannel(c); 1503 c.mServRspListener = listener; 1504 } 1505 1506 /** 1507 * Register a callback to be invoked on receiving Bonjour service discovery 1508 * response. 1509 * 1510 * <p> see {@link #discoverServices} for the detail. 1511 * 1512 * @param c 1513 * @param servListener is for listening to a Bonjour service response 1514 * @param txtListener is for listening to a Bonjour TXT record response 1515 */ setDnsSdResponseListeners(Channel c, DnsSdServiceResponseListener servListener, DnsSdTxtRecordListener txtListener)1516 public void setDnsSdResponseListeners(Channel c, 1517 DnsSdServiceResponseListener servListener, DnsSdTxtRecordListener txtListener) { 1518 checkChannel(c); 1519 c.mDnsSdServRspListener = servListener; 1520 c.mDnsSdTxtListener = txtListener; 1521 } 1522 1523 /** 1524 * Register a callback to be invoked on receiving upnp service discovery 1525 * response. 1526 * 1527 * <p> see {@link #discoverServices} for the detail. 1528 * 1529 * @param c is the channel created at {@link #initialize} 1530 * @param listener for callbacks on receiving service discovery response. 1531 */ setUpnpServiceResponseListener(Channel c, UpnpServiceResponseListener listener)1532 public void setUpnpServiceResponseListener(Channel c, 1533 UpnpServiceResponseListener listener) { 1534 checkChannel(c); 1535 c.mUpnpServRspListener = listener; 1536 } 1537 1538 /** 1539 * Initiate service discovery. A discovery process involves scanning for 1540 * requested services for the purpose of establishing a connection to a peer 1541 * that supports an available service. 1542 * 1543 * <p> The function call immediately returns after sending a request to start service 1544 * discovery to the framework. The application is notified of a success or failure to initiate 1545 * discovery through listener callbacks {@link ActionListener#onSuccess} or 1546 * {@link ActionListener#onFailure}. 1547 * 1548 * <p> The services to be discovered are specified with calls to {@link #addServiceRequest}. 1549 * 1550 * <p>The application is notified of the response against the service discovery request 1551 * through listener callbacks registered by {@link #setServiceResponseListener} or 1552 * {@link #setDnsSdResponseListeners}, or {@link #setUpnpServiceResponseListener}. 1553 * 1554 * @param c is the channel created at {@link #initialize} 1555 * @param listener for callbacks on success or failure. Can be null. 1556 */ 1557 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) discoverServices(Channel c, ActionListener listener)1558 public void discoverServices(Channel c, ActionListener listener) { 1559 checkChannel(c); 1560 c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, c.putListener(listener)); 1561 } 1562 1563 /** 1564 * Add a service discovery request. 1565 * 1566 * <p> The function call immediately returns after sending a request to add service 1567 * discovery request to the framework. The application is notified of a success or failure to 1568 * add service through listener callbacks {@link ActionListener#onSuccess} or 1569 * {@link ActionListener#onFailure}. 1570 * 1571 * <p>After service discovery request is added, you can initiate service discovery by 1572 * {@link #discoverServices}. 1573 * 1574 * <p>The added service requests can be cleared with calls to 1575 * {@link #removeServiceRequest(Channel, WifiP2pServiceRequest, ActionListener)} or 1576 * {@link #clearServiceRequests(Channel, ActionListener)}. 1577 * 1578 * @param c is the channel created at {@link #initialize} 1579 * @param req is the service discovery request. 1580 * @param listener for callbacks on success or failure. Can be null. 1581 */ addServiceRequest(Channel c, WifiP2pServiceRequest req, ActionListener listener)1582 public void addServiceRequest(Channel c, 1583 WifiP2pServiceRequest req, ActionListener listener) { 1584 checkChannel(c); 1585 checkServiceRequest(req); 1586 c.mAsyncChannel.sendMessage(ADD_SERVICE_REQUEST, 0, 1587 c.putListener(listener), req); 1588 } 1589 1590 /** 1591 * Remove a specified service discovery request added with {@link #addServiceRequest} 1592 * 1593 * <p> The function call immediately returns after sending a request to remove service 1594 * discovery request to the framework. The application is notified of a success or failure to 1595 * add service through listener callbacks {@link ActionListener#onSuccess} or 1596 * {@link ActionListener#onFailure}. 1597 * 1598 * @param c is the channel created at {@link #initialize} 1599 * @param req is the service discovery request. 1600 * @param listener for callbacks on success or failure. Can be null. 1601 */ removeServiceRequest(Channel c, WifiP2pServiceRequest req, ActionListener listener)1602 public void removeServiceRequest(Channel c, WifiP2pServiceRequest req, 1603 ActionListener listener) { 1604 checkChannel(c); 1605 checkServiceRequest(req); 1606 c.mAsyncChannel.sendMessage(REMOVE_SERVICE_REQUEST, 0, 1607 c.putListener(listener), req); 1608 } 1609 1610 /** 1611 * Clear all registered service discovery requests. 1612 * 1613 * <p> The function call immediately returns after sending a request to clear all 1614 * service discovery requests to the framework. The application is notified of a success 1615 * or failure to add service through listener callbacks {@link ActionListener#onSuccess} or 1616 * {@link ActionListener#onFailure}. 1617 * 1618 * @param c is the channel created at {@link #initialize} 1619 * @param listener for callbacks on success or failure. Can be null. 1620 */ clearServiceRequests(Channel c, ActionListener listener)1621 public void clearServiceRequests(Channel c, ActionListener listener) { 1622 checkChannel(c); 1623 c.mAsyncChannel.sendMessage(CLEAR_SERVICE_REQUESTS, 1624 0, c.putListener(listener)); 1625 } 1626 1627 /** 1628 * Request the current list of peers. 1629 * 1630 * @param c is the channel created at {@link #initialize} 1631 * @param listener for callback when peer list is available. Can be null. 1632 */ 1633 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) requestPeers(Channel c, PeerListListener listener)1634 public void requestPeers(Channel c, PeerListListener listener) { 1635 checkChannel(c); 1636 c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener)); 1637 } 1638 1639 /** 1640 * Request device connection info. 1641 * 1642 * @param c is the channel created at {@link #initialize} 1643 * @param listener for callback when connection info is available. Can be null. 1644 */ requestConnectionInfo(Channel c, ConnectionInfoListener listener)1645 public void requestConnectionInfo(Channel c, ConnectionInfoListener listener) { 1646 checkChannel(c); 1647 c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_INFO, 0, c.putListener(listener)); 1648 } 1649 1650 /** 1651 * Request p2p group info. 1652 * 1653 * @param c is the channel created at {@link #initialize} 1654 * @param listener for callback when group info is available. Can be null. 1655 */ 1656 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) requestGroupInfo(Channel c, GroupInfoListener listener)1657 public void requestGroupInfo(Channel c, GroupInfoListener listener) { 1658 checkChannel(c); 1659 c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO, 0, c.putListener(listener)); 1660 } 1661 1662 /** 1663 * Set p2p device name. 1664 * 1665 * @param c is the channel created at {@link #initialize} 1666 * @param listener for callback when group info is available. Can be null. 1667 * 1668 * @hide 1669 */ 1670 @SystemApi 1671 @RequiresPermission(anyOf = { 1672 android.Manifest.permission.NETWORK_SETTINGS, 1673 android.Manifest.permission.NETWORK_STACK, 1674 android.Manifest.permission.OVERRIDE_WIFI_CONFIG 1675 }) setDeviceName(@onNull Channel c, @NonNull String devName, @Nullable ActionListener listener)1676 public void setDeviceName(@NonNull Channel c, @NonNull String devName, 1677 @Nullable ActionListener listener) { 1678 checkChannel(c); 1679 WifiP2pDevice d = new WifiP2pDevice(); 1680 d.deviceName = devName; 1681 c.mAsyncChannel.sendMessage(SET_DEVICE_NAME, 0, c.putListener(listener), d); 1682 } 1683 1684 /** 1685 * Set Wifi Display information. 1686 * 1687 * @param c is the channel created at {@link #initialize} 1688 * @param wfdInfo the Wifi Display information to set 1689 * @param listener for callbacks on success or failure. Can be null. 1690 * 1691 * @hide 1692 */ 1693 @SystemApi 1694 @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) setWfdInfo(@onNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, @Nullable ActionListener listener)1695 public void setWfdInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, 1696 @Nullable ActionListener listener) { 1697 setWFDInfo(c, wfdInfo, listener); 1698 } 1699 1700 /** @hide */ 1701 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1702 @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) setWFDInfo(@onNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, @Nullable ActionListener listener)1703 public void setWFDInfo(@NonNull Channel c, @NonNull WifiP2pWfdInfo wfdInfo, 1704 @Nullable ActionListener listener) { 1705 checkChannel(c); 1706 try { 1707 mService.checkConfigureWifiDisplayPermission(); 1708 } catch (RemoteException e) { 1709 e.rethrowFromSystemServer(); 1710 } 1711 c.mAsyncChannel.sendMessage(SET_WFD_INFO, 0, c.putListener(listener), wfdInfo); 1712 } 1713 1714 1715 /** 1716 * Delete a stored persistent group from the system settings. 1717 * 1718 * <p> The function call immediately returns after sending a persistent group removal request 1719 * to the framework. The application is notified of a success or failure to initiate 1720 * group removal through listener callbacks {@link ActionListener#onSuccess} or 1721 * {@link ActionListener#onFailure}. 1722 * 1723 * <p>The persistent p2p group list stored in the system can be obtained by 1724 * {@link #requestPersistentGroupInfo(Channel, PersistentGroupInfoListener)} and 1725 * a network id can be obtained by {@link WifiP2pGroup#getNetworkId()}. 1726 * 1727 * @param c is the channel created at {@link #initialize} 1728 * @param netId the network id of the p2p group. 1729 * @param listener for callbacks on success or failure. Can be null. 1730 * 1731 * @hide 1732 */ 1733 @SystemApi 1734 @RequiresPermission(anyOf = { 1735 android.Manifest.permission.NETWORK_SETTINGS, 1736 android.Manifest.permission.NETWORK_STACK, 1737 android.Manifest.permission.OVERRIDE_WIFI_CONFIG 1738 }) deletePersistentGroup(@onNull Channel c, int netId, @Nullable ActionListener listener)1739 public void deletePersistentGroup(@NonNull Channel c, int netId, 1740 @Nullable ActionListener listener) { 1741 checkChannel(c); 1742 c.mAsyncChannel.sendMessage(DELETE_PERSISTENT_GROUP, netId, c.putListener(listener)); 1743 } 1744 1745 /** 1746 * Request a list of all the persistent p2p groups stored in system. 1747 * 1748 * @param c is the channel created at {@link #initialize} 1749 * @param listener for callback when persistent group info list is available. Can be null. 1750 * 1751 * @hide 1752 */ 1753 @SystemApi 1754 @RequiresPermission(anyOf = { 1755 android.Manifest.permission.NETWORK_SETTINGS, 1756 android.Manifest.permission.NETWORK_STACK, 1757 android.Manifest.permission.READ_WIFI_CREDENTIAL 1758 }) requestPersistentGroupInfo(@onNull Channel c, @Nullable PersistentGroupInfoListener listener)1759 public void requestPersistentGroupInfo(@NonNull Channel c, 1760 @Nullable PersistentGroupInfoListener listener) { 1761 checkChannel(c); 1762 c.mAsyncChannel.sendMessage(REQUEST_PERSISTENT_GROUP_INFO, 0, c.putListener(listener)); 1763 } 1764 1765 /** @hide */ 1766 @Retention(RetentionPolicy.SOURCE) 1767 @IntDef(prefix = {"MIRACAST_"}, value = { 1768 MIRACAST_DISABLED, 1769 MIRACAST_SOURCE, 1770 MIRACAST_SINK}) 1771 public @interface MiracastMode {} 1772 1773 /** 1774 * Miracast is disabled. 1775 * @hide 1776 */ 1777 @SystemApi 1778 public static final int MIRACAST_DISABLED = 0; 1779 /** 1780 * Device acts as a Miracast source. 1781 * @hide 1782 */ 1783 @SystemApi 1784 public static final int MIRACAST_SOURCE = 1; 1785 /** 1786 * Device acts as a Miracast sink. 1787 * @hide 1788 */ 1789 @SystemApi 1790 public static final int MIRACAST_SINK = 2; 1791 1792 /** 1793 * This is used to provide information to drivers to optimize performance depending 1794 * on the current mode of operation. 1795 * {@link #MIRACAST_DISABLED} - disabled 1796 * {@link #MIRACAST_SOURCE} - source operation 1797 * {@link #MIRACAST_SINK} - sink operation 1798 * 1799 * As an example, the driver could reduce the channel dwell time during scanning 1800 * when acting as a source or sink to minimize impact on Miracast. 1801 * 1802 * @param mode mode of operation. One of {@link #MIRACAST_DISABLED}, {@link #MIRACAST_SOURCE}, 1803 * or {@link #MIRACAST_SINK} 1804 * 1805 * @hide 1806 */ 1807 @SystemApi 1808 @RequiresPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY) setMiracastMode(@iracastMode int mode)1809 public void setMiracastMode(@MiracastMode int mode) { 1810 try { 1811 mService.setMiracastMode(mode); 1812 } catch (RemoteException e) { 1813 throw e.rethrowFromSystemServer(); 1814 } 1815 } 1816 getMessenger(@onNull Binder binder, @Nullable String packageName)1817 private Messenger getMessenger(@NonNull Binder binder, @Nullable String packageName) { 1818 try { 1819 return mService.getMessenger(binder, packageName); 1820 } catch (RemoteException e) { 1821 throw e.rethrowFromSystemServer(); 1822 } 1823 } 1824 1825 /** 1826 * Get a reference to WifiP2pService handler. This is used to establish 1827 * an AsyncChannel communication with WifiService 1828 * 1829 * @param binder A binder for the service to associate with this client. 1830 * 1831 * @return Messenger pointing to the WifiP2pService handler 1832 * @hide 1833 */ getMessenger(Binder binder)1834 public Messenger getMessenger(Binder binder) { 1835 // No way to determine package name in this case. 1836 return getMessenger(binder, null); 1837 } 1838 1839 /** 1840 * Get a reference to P2pStateMachine handler. This is used to establish 1841 * a priveleged AsyncChannel communication with WifiP2pService. 1842 * 1843 * @return Messenger pointing to the WifiP2pService handler 1844 * @hide 1845 */ getP2pStateMachineMessenger()1846 public Messenger getP2pStateMachineMessenger() { 1847 try { 1848 return mService.getP2pStateMachineMessenger(); 1849 } catch (RemoteException e) { 1850 throw e.rethrowFromSystemServer(); 1851 } 1852 } 1853 1854 /** 1855 * Get a handover request message for use in WFA NFC Handover transfer. 1856 * @hide 1857 */ getNfcHandoverRequest(Channel c, HandoverMessageListener listener)1858 public void getNfcHandoverRequest(Channel c, HandoverMessageListener listener) { 1859 checkChannel(c); 1860 c.mAsyncChannel.sendMessage(GET_HANDOVER_REQUEST, 0, c.putListener(listener)); 1861 } 1862 1863 1864 /** 1865 * Get a handover select message for use in WFA NFC Handover transfer. 1866 * @hide 1867 */ getNfcHandoverSelect(Channel c, HandoverMessageListener listener)1868 public void getNfcHandoverSelect(Channel c, HandoverMessageListener listener) { 1869 checkChannel(c); 1870 c.mAsyncChannel.sendMessage(GET_HANDOVER_SELECT, 0, c.putListener(listener)); 1871 } 1872 1873 /** 1874 * @hide 1875 */ initiatorReportNfcHandover(Channel c, String handoverSelect, ActionListener listener)1876 public void initiatorReportNfcHandover(Channel c, String handoverSelect, 1877 ActionListener listener) { 1878 checkChannel(c); 1879 Bundle bundle = new Bundle(); 1880 bundle.putString(EXTRA_HANDOVER_MESSAGE, handoverSelect); 1881 c.mAsyncChannel.sendMessage(INITIATOR_REPORT_NFC_HANDOVER, 0, 1882 c.putListener(listener), bundle); 1883 } 1884 1885 1886 /** 1887 * @hide 1888 */ responderReportNfcHandover(Channel c, String handoverRequest, ActionListener listener)1889 public void responderReportNfcHandover(Channel c, String handoverRequest, 1890 ActionListener listener) { 1891 checkChannel(c); 1892 Bundle bundle = new Bundle(); 1893 bundle.putString(EXTRA_HANDOVER_MESSAGE, handoverRequest); 1894 c.mAsyncChannel.sendMessage(RESPONDER_REPORT_NFC_HANDOVER, 0, 1895 c.putListener(listener), bundle); 1896 } 1897 1898 /** 1899 * Removes all saved p2p groups. 1900 * 1901 * @param c is the channel created at {@link #initialize}. 1902 * @param listener for callback on success or failure. Can be null. 1903 * 1904 * @hide 1905 */ 1906 @SystemApi 1907 @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) factoryReset(@onNull Channel c, @Nullable ActionListener listener)1908 public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) { 1909 checkChannel(c); 1910 c.mAsyncChannel.sendMessage(FACTORY_RESET, 0, c.putListener(listener)); 1911 } 1912 1913 /** 1914 * Request saved WifiP2pConfig which used for an ongoing peer connection 1915 * 1916 * @param c is the channel created at {@link #initialize} 1917 * @param listener for callback when ongoing peer config updated. Can't be null. 1918 * 1919 * @hide 1920 */ 1921 @RequiresPermission(android.Manifest.permission.NETWORK_STACK) requestOngoingPeerConfig(@onNull Channel c, @NonNull OngoingPeerInfoListener listener)1922 public void requestOngoingPeerConfig(@NonNull Channel c, 1923 @NonNull OngoingPeerInfoListener listener) { 1924 checkChannel(c); 1925 c.mAsyncChannel.sendMessage(REQUEST_ONGOING_PEER_CONFIG, 1926 Binder.getCallingUid(), c.putListener(listener)); 1927 } 1928 1929 /** 1930 * Set saved WifiP2pConfig which used for an ongoing peer connection 1931 * 1932 * @param c is the channel created at {@link #initialize} 1933 * @param config used for change an ongoing peer connection 1934 * @param listener for callback when ongoing peer config updated. Can be null. 1935 * 1936 * @hide 1937 */ 1938 @RequiresPermission(android.Manifest.permission.NETWORK_STACK) setOngoingPeerConfig(@onNull Channel c, @NonNull WifiP2pConfig config, @Nullable ActionListener listener)1939 public void setOngoingPeerConfig(@NonNull Channel c, @NonNull WifiP2pConfig config, 1940 @Nullable ActionListener listener) { 1941 checkChannel(c); 1942 checkP2pConfig(config); 1943 c.mAsyncChannel.sendMessage(SET_ONGOING_PEER_CONFIG, 0, 1944 c.putListener(listener), config); 1945 } 1946 1947 /** 1948 * Request p2p enabled state. 1949 * 1950 * <p> This state indicates whether Wi-Fi p2p is enabled or disabled. 1951 * The valid value is one of {@link #WIFI_P2P_STATE_DISABLED} or 1952 * {@link #WIFI_P2P_STATE_ENABLED}. The state is returned using the 1953 * {@link P2pStateListener} listener. 1954 * 1955 * <p> This state is also included in the {@link #WIFI_P2P_STATE_CHANGED_ACTION} 1956 * broadcast event with extra {@link #EXTRA_WIFI_STATE}. 1957 * 1958 * @param c is the channel created at {@link #initialize}. 1959 * @param listener for callback when p2p state is available.. 1960 */ requestP2pState(@onNull Channel c, @NonNull P2pStateListener listener)1961 public void requestP2pState(@NonNull Channel c, 1962 @NonNull P2pStateListener listener) { 1963 checkChannel(c); 1964 if (listener == null) throw new IllegalArgumentException("This listener cannot be null."); 1965 c.mAsyncChannel.sendMessage(REQUEST_P2P_STATE, 0, c.putListener(listener)); 1966 } 1967 1968 /** 1969 * Request p2p discovery state. 1970 * 1971 * <p> This state indicates whether p2p discovery has started or stopped. 1972 * The valid value is one of {@link #WIFI_P2P_DISCOVERY_STARTED} or 1973 * {@link #WIFI_P2P_DISCOVERY_STOPPED}. The state is returned using the 1974 * {@link DiscoveryStateListener} listener. 1975 * 1976 * <p> This state is also included in the {@link #WIFI_P2P_DISCOVERY_CHANGED_ACTION} 1977 * broadcast event with extra {@link #EXTRA_DISCOVERY_STATE}. 1978 * 1979 * @param c is the channel created at {@link #initialize}. 1980 * @param listener for callback when discovery state is available.. 1981 */ requestDiscoveryState(@onNull Channel c, @NonNull DiscoveryStateListener listener)1982 public void requestDiscoveryState(@NonNull Channel c, 1983 @NonNull DiscoveryStateListener listener) { 1984 checkChannel(c); 1985 if (listener == null) throw new IllegalArgumentException("This listener cannot be null."); 1986 c.mAsyncChannel.sendMessage(REQUEST_DISCOVERY_STATE, 0, c.putListener(listener)); 1987 } 1988 1989 /** 1990 * Request network info. 1991 * 1992 * <p> This method provides the network info in the form of a {@link android.net.NetworkInfo}. 1993 * {@link android.net.NetworkInfo#isAvailable()} indicates the p2p availability and 1994 * {@link android.net.NetworkInfo#getDetailedState()} reports the current fine-grained state 1995 * of the network. This {@link android.net.NetworkInfo} is returned using the 1996 * {@link NetworkInfoListener} listener. 1997 * 1998 * <p> This information is also included in the {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} 1999 * broadcast event with extra {@link #EXTRA_NETWORK_INFO}. 2000 * 2001 * @param c is the channel created at {@link #initialize}. 2002 * @param listener for callback when network info is available.. 2003 */ requestNetworkInfo(@onNull Channel c, @NonNull NetworkInfoListener listener)2004 public void requestNetworkInfo(@NonNull Channel c, 2005 @NonNull NetworkInfoListener listener) { 2006 checkChannel(c); 2007 if (listener == null) throw new IllegalArgumentException("This listener cannot be null."); 2008 c.mAsyncChannel.sendMessage(REQUEST_NETWORK_INFO, 0, c.putListener(listener)); 2009 } 2010 2011 /** 2012 * Request Device Info 2013 * 2014 * <p> This method provides the device info 2015 * in the form of a {@link android.net.wifi.p2p.WifiP2pDevice}. 2016 * Valid {@link android.net.wifi.p2p.WifiP2pDevice} is returned when p2p is enabled. 2017 * To get information notifications on P2P getting enabled refers 2018 * {@link #WIFI_P2P_STATE_ENABLED}. 2019 * 2020 * <p> This {@link android.net.wifi.p2p.WifiP2pDevice} is returned using the 2021 * {@link DeviceInfoListener} listener. 2022 * 2023 * <p> {@link android.net.wifi.p2p.WifiP2pDevice#deviceAddress} is only available if the caller 2024 * holds the {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} permission, and holds the 2025 * anonymized MAC address (02:00:00:00:00:00) otherwise. 2026 * 2027 * <p> This information is also included in the {@link #WIFI_P2P_THIS_DEVICE_CHANGED_ACTION} 2028 * broadcast event with extra {@link #EXTRA_WIFI_P2P_DEVICE}. 2029 * 2030 * @param c is the channel created at {@link #initialize(Context, Looper, ChannelListener)}. 2031 * @param listener for callback when network info is available. 2032 */ 2033 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) requestDeviceInfo(@onNull Channel c, @NonNull DeviceInfoListener listener)2034 public void requestDeviceInfo(@NonNull Channel c, @NonNull DeviceInfoListener listener) { 2035 checkChannel(c); 2036 if (listener == null) throw new IllegalArgumentException("This listener cannot be null."); 2037 c.mAsyncChannel.sendMessage(REQUEST_DEVICE_INFO, 0, c.putListener(listener)); 2038 } 2039 } 2040