1 /* 2 * Copyright (C) 2017 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 com.googlecode.android_scripting.facade.wifi; 18 19 import android.app.Service; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.net.NetworkInfo; 25 import android.net.wifi.WpsInfo; 26 import android.net.wifi.p2p.WifiP2pConfig; 27 import android.net.wifi.p2p.WifiP2pDevice; 28 import android.net.wifi.p2p.WifiP2pDeviceList; 29 import android.net.wifi.p2p.WifiP2pGroup; 30 import android.net.wifi.p2p.WifiP2pGroupList; 31 import android.net.wifi.p2p.WifiP2pInfo; 32 import android.net.wifi.p2p.WifiP2pManager; 33 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo; 34 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceRequest; 35 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; 36 import android.net.wifi.p2p.nsd.WifiP2pServiceRequest; 37 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo; 38 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest; 39 import android.os.Bundle; 40 import android.os.Message; 41 import android.os.Messenger; 42 import android.os.RemoteException; 43 44 import com.android.internal.util.Protocol; 45 46 import com.googlecode.android_scripting.Log; 47 import com.googlecode.android_scripting.facade.EventFacade; 48 import com.googlecode.android_scripting.facade.FacadeManager; 49 import com.googlecode.android_scripting.jsonrpc.RpcReceiver; 50 import com.googlecode.android_scripting.rpc.Rpc; 51 import com.googlecode.android_scripting.rpc.RpcParameter; 52 53 import org.json.JSONArray; 54 import org.json.JSONException; 55 import org.json.JSONObject; 56 57 import java.net.InetAddress; 58 import java.util.ArrayList; 59 import java.util.Collection; 60 import java.util.HashMap; 61 import java.util.Iterator; 62 import java.util.List; 63 import java.util.Map; 64 65 /** 66 * WifiP2pManager functions. 67 */ 68 public class WifiP2pManagerFacade extends RpcReceiver { 69 70 class WifiP2pActionListener implements WifiP2pManager.ActionListener { 71 private final EventFacade mEventFacade; 72 private final String mEventType; 73 private final String TAG; 74 75 public WifiP2pActionListener(EventFacade eventFacade, String tag) { 76 mEventType = "WifiP2p"; 77 mEventFacade = eventFacade; 78 TAG = tag; 79 } 80 81 @Override 82 public void onSuccess() { 83 mEventFacade.postEvent(mEventType + TAG + "OnSuccess", null); 84 } 85 86 @Override 87 public void onFailure(int reason) { 88 Log.d("WifiActionListener " + mEventType); 89 Bundle msg = new Bundle(); 90 if (reason == WifiP2pManager.P2P_UNSUPPORTED) { 91 msg.putString("reason", "P2P_UNSUPPORTED"); 92 } else if (reason == WifiP2pManager.ERROR) { 93 msg.putString("reason", "ERROR"); 94 } else if (reason == WifiP2pManager.BUSY) { 95 msg.putString("reason", "BUSY"); 96 } else if (reason == WifiP2pManager.NO_SERVICE_REQUESTS) { 97 msg.putString("reason", "NO_SERVICE_REQUESTS"); 98 } else { 99 msg.putInt("reason", reason); 100 } 101 mEventFacade.postEvent(mEventType + TAG + "OnFailure", msg); 102 } 103 } 104 105 class WifiP2pConnectionInfoListener implements WifiP2pManager.ConnectionInfoListener { 106 private final EventFacade mEventFacade; 107 private final String mEventType; 108 109 public WifiP2pConnectionInfoListener(EventFacade eventFacade) { 110 mEventType = "WifiP2p"; 111 mEventFacade = eventFacade; 112 } 113 114 @Override 115 public void onConnectionInfoAvailable(WifiP2pInfo info) { 116 Bundle msg = new Bundle(); 117 msg.putBoolean("groupFormed", info.groupFormed); 118 msg.putBoolean("isGroupOwner", info.isGroupOwner); 119 InetAddress addr = info.groupOwnerAddress; 120 String hostName = null; 121 String hostAddress = null; 122 if (addr != null) { 123 hostName = addr.getHostName(); 124 hostAddress = addr.getHostAddress(); 125 } 126 msg.putString("groupOwnerHostName", hostName); 127 msg.putString("groupOwnerHostAddress", hostAddress); 128 mEventFacade.postEvent(mEventType + "OnConnectionInfoAvailable", msg); 129 } 130 } 131 132 class WifiP2pDnsSdServiceResponseListener implements 133 WifiP2pManager.DnsSdServiceResponseListener { 134 private final EventFacade mEventFacade; 135 private final String mEventType; 136 137 public WifiP2pDnsSdServiceResponseListener(EventFacade eventFacade) { 138 mEventType = "WifiP2p"; 139 mEventFacade = eventFacade; 140 } 141 142 @Override 143 public void onDnsSdServiceAvailable(String instanceName, String registrationType, 144 WifiP2pDevice srcDevice) { 145 Bundle msg = new Bundle(); 146 msg.putString("InstanceName", instanceName); 147 msg.putString("RegistrationType", registrationType); 148 msg.putString("SourceDeviceName", srcDevice.deviceName); 149 msg.putString("SourceDeviceAddress", srcDevice.deviceAddress); 150 mEventFacade.postEvent(mEventType + "OnDnsSdServiceAvailable", msg); 151 } 152 } 153 154 class WifiP2pDnsSdTxtRecordListener implements WifiP2pManager.DnsSdTxtRecordListener { 155 private final EventFacade mEventFacade; 156 private final String mEventType; 157 158 public WifiP2pDnsSdTxtRecordListener(EventFacade eventFacade) { 159 mEventType = "WifiP2p"; 160 mEventFacade = eventFacade; 161 } 162 163 @Override 164 public void onDnsSdTxtRecordAvailable(String fullDomainName, 165 Map<String, String> txtRecordMap, WifiP2pDevice srcDevice) { 166 Bundle msg = new Bundle(); 167 msg.putString("FullDomainName", fullDomainName); 168 Bundle txtMap = new Bundle(); 169 for (String key : txtRecordMap.keySet()) { 170 txtMap.putString(key, txtRecordMap.get(key)); 171 } 172 msg.putBundle("TxtRecordMap", txtMap); 173 msg.putString("SourceDeviceName", srcDevice.deviceName); 174 msg.putString("SourceDeviceAddress", srcDevice.deviceAddress); 175 mEventFacade.postEvent(mEventType + "OnDnsSdTxtRecordAvailable", msg); 176 } 177 } 178 179 class WifiP2pGroupInfoListener implements WifiP2pManager.GroupInfoListener { 180 private final EventFacade mEventFacade; 181 private final String mEventType; 182 183 public WifiP2pGroupInfoListener(EventFacade eventFacade) { 184 mEventType = "WifiP2p"; 185 mEventFacade = eventFacade; 186 } 187 188 @Override 189 public void onGroupInfoAvailable(WifiP2pGroup group) { 190 mEventFacade.postEvent(mEventType + "OnGroupInfoAvailable", parseGroupInfo(group)); 191 } 192 } 193 194 class WifiP2pPeerListListener implements WifiP2pManager.PeerListListener { 195 private final EventFacade mEventFacade; 196 197 public WifiP2pPeerListListener(EventFacade eventFacade) { 198 mEventFacade = eventFacade; 199 } 200 201 @Override 202 public void onPeersAvailable(WifiP2pDeviceList newPeers) { 203 Collection<WifiP2pDevice> devices = newPeers.getDeviceList(); 204 Log.d(devices.toString()); 205 if (devices.size() > 0) { 206 mP2pPeers.clear(); 207 mP2pPeers.addAll(devices); 208 Bundle msg = new Bundle(); 209 msg.putParcelableList("Peers", mP2pPeers); 210 mEventFacade.postEvent(mEventType + "OnPeersAvailable", msg); 211 } 212 } 213 } 214 215 class WifiP2pPersistentGroupInfoListener implements WifiP2pManager.PersistentGroupInfoListener { 216 private final EventFacade mEventFacade; 217 private final String mEventType; 218 219 public WifiP2pPersistentGroupInfoListener(EventFacade eventFacade) { 220 mEventType = "WifiP2p"; 221 mEventFacade = eventFacade; 222 } 223 224 @Override 225 public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) { 226 ArrayList<Bundle> gs = new ArrayList<Bundle>(); 227 for (WifiP2pGroup g : groups.getGroupList()) { 228 gs.add(parseGroupInfo(g)); 229 } 230 mEventFacade.postEvent(mEventType + "OnPersistentGroupInfoAvailable", gs); 231 } 232 } 233 234 class WifiP2pOngoingPeerConfigListener implements WifiP2pManager.OngoingPeerInfoListener { 235 private final EventFacade mEventFacade; 236 private final String mEventType; 237 238 WifiP2pOngoingPeerConfigListener(EventFacade eventFacade) { 239 mEventType = "WifiP2p"; 240 mEventFacade = eventFacade; 241 } 242 243 @Override 244 public void onOngoingPeerAvailable(WifiP2pConfig config) { 245 Bundle msg = new Bundle(); 246 mEventFacade.postEvent(mEventType + "OnOngoingPeerAvailable", config); 247 } 248 } 249 250 class WifiP2pUpnpServiceResponseListener implements WifiP2pManager.UpnpServiceResponseListener { 251 private final EventFacade mEventFacade; 252 private final String mEventType; 253 254 WifiP2pUpnpServiceResponseListener(EventFacade eventFacade) { 255 mEventType = "WifiP2p"; 256 mEventFacade = eventFacade; 257 } 258 259 @Override 260 public void onUpnpServiceAvailable(List<String> uniqueServiceNames, 261 WifiP2pDevice srcDevice) { 262 Bundle msg = new Bundle(); 263 msg.putParcelable("Device", srcDevice); 264 msg.putStringArrayList("ServiceList", new ArrayList(uniqueServiceNames)); 265 mEventFacade.postEvent(mEventType + "OnUpnpServiceAvailable", msg); 266 } 267 } 268 269 class WifiP2pStateChangedReceiver extends BroadcastReceiver { 270 private final EventFacade mEventFacade; 271 272 WifiP2pStateChangedReceiver(EventFacade eventFacade) { 273 mEventFacade = eventFacade; 274 } 275 276 @Override 277 public void onReceive(Context c, Intent intent) { 278 Bundle mResults = new Bundle(); 279 String action = intent.getAction(); 280 if (action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) { 281 Log.d("Wifi P2p State Changed."); 282 int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, 0); 283 if (state == WifiP2pManager.WIFI_P2P_STATE_DISABLED) { 284 Log.d("Disabled"); 285 isP2pEnabled = false; 286 } else if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { 287 Log.d("Enabled"); 288 isP2pEnabled = true; 289 } 290 } else if (action.equals(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)) { 291 Log.d("Wifi P2p Peers Changed. Requesting peers."); 292 WifiP2pDeviceList peers = intent 293 .getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST); 294 Log.d(peers.toString()); 295 wifiP2pRequestPeers(); 296 } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { 297 Log.d("Wifi P2p Connection Changed."); 298 WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO); 299 NetworkInfo networkInfo = intent 300 .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); 301 WifiP2pGroup group = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP); 302 if (networkInfo.isConnected()) { 303 Log.d("Wifi P2p Connected."); 304 mResults.putParcelable("P2pInfo", p2pInfo); 305 mResults.putParcelable("Group", group); 306 mEventFacade.postEvent(mEventType + "Connected", mResults); 307 } else { 308 mEventFacade.postEvent(mEventType + "Disconnected", null); 309 } 310 } else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) { 311 Log.d("Wifi P2p This Device Changed."); 312 WifiP2pDevice device = intent 313 .getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE); 314 mResults.putParcelable("Device", device); 315 mEventFacade.postEvent(mEventType + "ThisDeviceChanged", mResults); 316 } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) { 317 Log.d("Wifi P2p Discovery Changed."); 318 int state = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, 0); 319 if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) { 320 Log.d("discovery started."); 321 } else if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED) { 322 Log.d("discovery stoped."); 323 } 324 } 325 } 326 } 327 328 private final static String mEventType = "WifiP2p"; 329 330 private WifiP2pManager.Channel mChannel; 331 private final EventFacade mEventFacade; 332 private final WifiP2pManager mP2p; 333 private final WifiP2pStateChangedReceiver mP2pStateChangedReceiver; 334 private final Service mService; 335 private final IntentFilter mStateChangeFilter; 336 private final Map<Integer, WifiP2pServiceRequest> mServiceRequests; 337 338 private boolean isP2pEnabled; 339 private int mServiceRequestCnt = 0; 340 private WifiP2pServiceInfo mServiceInfo = null; 341 private List<WifiP2pDevice> mP2pPeers = new ArrayList<WifiP2pDevice>(); 342 343 public WifiP2pManagerFacade(FacadeManager manager) { 344 super(manager); 345 mService = manager.getService(); 346 mP2p = (WifiP2pManager) mService.getSystemService(Context.WIFI_P2P_SERVICE); 347 mEventFacade = manager.getReceiver(EventFacade.class); 348 349 mStateChangeFilter = new IntentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); 350 mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); 351 mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); 352 mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); 353 mStateChangeFilter.setPriority(999); 354 355 mP2pStateChangedReceiver = new WifiP2pStateChangedReceiver(mEventFacade); 356 mServiceRequests = new HashMap<Integer, WifiP2pServiceRequest>(); 357 } 358 359 public Bundle parseGroupInfo(WifiP2pGroup group) { 360 Bundle msg = new Bundle(); 361 msg.putString("Interface", group.getInterface()); 362 msg.putString("NetworkName", group.getNetworkName()); 363 msg.putString("Passphrase", group.getPassphrase()); 364 msg.putInt("NetworkId", group.getNetworkId()); 365 msg.putString("OwnerName", group.getOwner().deviceName); 366 msg.putString("OwnerAddress", group.getOwner().deviceAddress); 367 return msg; 368 } 369 370 @Override 371 public void shutdown() { 372 mService.unregisterReceiver(mP2pStateChangedReceiver); 373 } 374 375 @Rpc(description = "Accept p2p connection invitation.") 376 public void wifiP2pAcceptConnection() throws RemoteException { 377 Log.d("Accepting p2p connection."); 378 Messenger m = mP2p.getP2pStateMachineMessenger(); 379 int user_accept = Protocol.BASE_WIFI_P2P_SERVICE + 2; 380 Message msg = Message.obtain(); 381 msg.what = user_accept; 382 m.send(msg); 383 } 384 385 @Rpc(description = "Reject p2p connection invitation.") 386 public void wifiP2pRejectConnection() throws RemoteException { 387 Log.d("Rejecting p2p connection."); 388 Messenger m = mP2p.getP2pStateMachineMessenger(); 389 int user_accept = Protocol.BASE_WIFI_P2P_SERVICE + 3; 390 Message msg = Message.obtain(); 391 msg.what = user_accept; 392 m.send(msg); 393 } 394 395 /** 396 * Confirm p2p keypad connection invitation. 397 */ 398 @Rpc(description = "Confirm p2p keypad connection invitation.") 399 public void wifiP2pConfirmConnection() throws RemoteException { 400 Log.d("Confirm p2p connection."); 401 Messenger m = mP2p.getP2pStateMachineMessenger(); 402 int user_confirm = Protocol.BASE_WIFI_P2P_SERVICE + 7; 403 Message msg = Message.obtain(); 404 msg.what = user_confirm; 405 m.send(msg); 406 } 407 408 @Rpc(description = "Register a local service for service discovery. One of the \"CreateXxxServiceInfo functions needs to be called first.\"") 409 public void wifiP2pAddLocalService() { 410 mP2p.addLocalService(mChannel, mServiceInfo, 411 new WifiP2pActionListener(mEventFacade, "AddLocalService")); 412 } 413 414 @Rpc(description = "Add a service discovery request.") 415 public Integer wifiP2pAddServiceRequest( 416 @RpcParameter(name = "protocolType") Integer protocolType) { 417 WifiP2pServiceRequest request = WifiP2pServiceRequest.newInstance(protocolType); 418 mServiceRequestCnt += 1; 419 mServiceRequests.put(mServiceRequestCnt, request); 420 mP2p.addServiceRequest(mChannel, request, new WifiP2pActionListener(mEventFacade, 421 "AddServiceRequest")); 422 return mServiceRequestCnt; 423 } 424 425 /** 426 * Add a service upnp discovery request. 427 * @param query The part of service specific query 428 */ 429 @Rpc(description = "Add a service upnp discovery request.") 430 public Integer wifiP2pAddUpnpServiceRequest( 431 @RpcParameter(name = "query") String query) { 432 WifiP2pUpnpServiceRequest request = WifiP2pUpnpServiceRequest.newInstance(query); 433 mServiceRequestCnt += 1; 434 mServiceRequests.put(mServiceRequestCnt, request); 435 mP2p.addServiceRequest(mChannel, request, new WifiP2pActionListener(mEventFacade, 436 "AddUpnpServiceRequest")); 437 return mServiceRequestCnt; 438 } 439 440 /** 441 * Create a service discovery request to get the TXT data from the specified 442 * Bonjour service. 443 * 444 * @param instanceName instance name. Can be null. 445 * e.g) 446 * "MyPrinter" 447 * @param serviceType service type. Cannot be null. 448 * e.g) 449 * "_afpovertcp._tcp."(Apple File Sharing over TCP) 450 * "_ipp._tcp" (IP Printing over TCP) 451 * "_http._tcp" (http service) 452 */ 453 @Rpc(description = "Add a service dns discovery request.") 454 public Integer wifiP2pAddDnssdServiceRequest( 455 @RpcParameter(name = "serviceType") String serviceType, 456 @RpcParameter(name = "instanceName") String instanceName) { 457 WifiP2pDnsSdServiceRequest request; 458 if (instanceName != null) { 459 request = WifiP2pDnsSdServiceRequest.newInstance(instanceName, serviceType); 460 } else { 461 request = WifiP2pDnsSdServiceRequest.newInstance(serviceType); 462 } 463 mServiceRequestCnt += 1; 464 mServiceRequests.put(mServiceRequestCnt, request); 465 mP2p.addServiceRequest(mChannel, request, new WifiP2pActionListener(mEventFacade, 466 "AddDnssdServiceRequest")); 467 return mServiceRequestCnt; 468 } 469 470 @Rpc(description = "Cancel any ongoing connect negotiation.") 471 public void wifiP2pCancelConnect() { 472 mP2p.cancelConnect(mChannel, new WifiP2pActionListener(mEventFacade, "CancelConnect")); 473 } 474 475 @Rpc(description = "Clear all registered local services of service discovery.") 476 public void wifiP2pClearLocalServices() { 477 mP2p.clearLocalServices(mChannel, 478 new WifiP2pActionListener(mEventFacade, "ClearLocalServices")); 479 } 480 481 @Rpc(description = "Clear all registered service discovery requests.") 482 public void wifiP2pClearServiceRequests() { 483 mP2p.clearServiceRequests(mChannel, 484 new WifiP2pActionListener(mEventFacade, "ClearServiceRequests")); 485 } 486 487 /** 488 * Connects to a discovered wifi p2p device 489 * @param config JSONObject Dictionary of p2p connection parameters 490 * @throws JSONException 491 */ 492 @Rpc(description = "Connects to a discovered wifi p2p device.") 493 public void wifiP2pConnect(@RpcParameter(name = "config") JSONObject config) 494 throws JSONException { 495 WifiP2pConfig wifiP2pConfig = genWifiP2pConfig(config); 496 mP2p.connect(mChannel, wifiP2pConfig, 497 new WifiP2pActionListener(mEventFacade, "Connect")); 498 } 499 500 @Rpc(description = "Create a Bonjour service info object to be used for wifiP2pAddLocalService.") 501 public void wifiP2pCreateBonjourServiceInfo( 502 @RpcParameter(name = "instanceName") String instanceName, 503 @RpcParameter(name = "serviceType") String serviceType, 504 @RpcParameter(name = "txtMap") JSONObject txtMap) throws JSONException { 505 Map<String, String> map = new HashMap<String, String>(); 506 Iterator<String> keyIterator = txtMap.keys(); 507 while (keyIterator.hasNext()) { 508 String key = keyIterator.next(); 509 map.put(key, txtMap.getString(key)); 510 } 511 mServiceInfo = WifiP2pDnsSdServiceInfo.newInstance(instanceName, serviceType, map); 512 } 513 514 @Rpc(description = "Create a wifi p2p group.") 515 public void wifiP2pCreateGroup() { 516 mP2p.createGroup(mChannel, new WifiP2pActionListener(mEventFacade, "CreateGroup")); 517 } 518 519 /** 520 * Create a group with config. 521 * 522 * @param config JSONObject Dictionary of p2p connection parameters 523 * @throws JSONException 524 */ 525 @Rpc(description = "Create a wifi p2p group with config.") 526 public void wifiP2pCreateGroupWithConfig(@RpcParameter(name = "config") JSONObject config) 527 throws JSONException { 528 WifiP2pConfig wifiP2pConfig = genWifiP2pConfig(config); 529 mP2p.createGroup(mChannel, wifiP2pConfig, 530 new WifiP2pActionListener(mEventFacade, "CreateGroup")); 531 } 532 533 @Rpc(description = "Create a Upnp service info object to be used for wifiP2pAddLocalService.") 534 public void wifiP2pCreateUpnpServiceInfo( 535 @RpcParameter(name = "uuid") String uuid, 536 @RpcParameter(name = "device") String device, 537 @RpcParameter(name = "services") JSONArray services) throws JSONException { 538 List<String> serviceList = new ArrayList<String>(); 539 for (int i = 0; i < services.length(); i++) { 540 serviceList.add(services.getString(i)); 541 Log.d("wifiP2pCreateUpnpServiceInfo, services: " + services.getString(i)); 542 } 543 mServiceInfo = WifiP2pUpnpServiceInfo.newInstance(uuid, device, serviceList); 544 } 545 546 @Rpc(description = "Delete a stored persistent group from the system settings.") 547 public void wifiP2pDeletePersistentGroup(@RpcParameter(name = "netId") Integer netId) { 548 mP2p.deletePersistentGroup(mChannel, netId, 549 new WifiP2pActionListener(mEventFacade, "DeletePersistentGroup")); 550 } 551 552 private boolean wifiP2pDeviceMatches(WifiP2pDevice d, String deviceId) { 553 return d.deviceName.equals(deviceId) || d.deviceAddress.equals(deviceId); 554 } 555 556 @Rpc(description = "Start peers discovery for wifi p2p.") 557 public void wifiP2pDiscoverPeers() { 558 mP2p.discoverPeers(mChannel, new WifiP2pActionListener(mEventFacade, "DiscoverPeers")); 559 } 560 561 @Rpc(description = "Initiate service discovery.") 562 public void wifiP2pDiscoverServices() { 563 mP2p.discoverServices(mChannel, 564 new WifiP2pActionListener(mEventFacade, "DiscoverServices")); 565 } 566 567 @Rpc(description = "Initialize wifi p2p. Must be called before any other p2p functions.") 568 public void wifiP2pInitialize() { 569 mService.registerReceiver(mP2pStateChangedReceiver, mStateChangeFilter); 570 mChannel = mP2p.initialize(mService, mService.getMainLooper(), null); 571 } 572 573 @Rpc(description = "Sets the listening channel and operating channel of the current group created with initialize") 574 public void wifiP2pSetChannelsForCurrentGroup( 575 @RpcParameter(name = "listeningChannel") Integer listeningChannel, 576 @RpcParameter(name = "operatingChannel") Integer operatingChannel) { 577 mP2p.setWifiP2pChannels(mChannel, listeningChannel, operatingChannel, 578 new WifiP2pActionListener(mEventFacade, "SetChannels")); 579 } 580 581 @Rpc(description = "Close the current wifi p2p connection created with initialize.") 582 public void wifiP2pClose() { 583 if (mChannel != null) { 584 mChannel.close(); 585 } 586 } 587 588 @Rpc(description = "Returns true if wifi p2p is enabled, false otherwise.") 589 public Boolean wifiP2pIsEnabled() { 590 return isP2pEnabled; 591 } 592 593 @Rpc(description = "Remove the current p2p group.") 594 public void wifiP2pRemoveGroup() { 595 mP2p.removeGroup(mChannel, new WifiP2pActionListener(mEventFacade, "RemoveGroup")); 596 } 597 598 @Rpc(description = "Remove a registered local service added with wifiP2pAddLocalService.") 599 public void wifiP2pRemoveLocalService() { 600 mP2p.removeLocalService(mChannel, mServiceInfo, 601 new WifiP2pActionListener(mEventFacade, "RemoveLocalService")); 602 } 603 604 @Rpc(description = "Remove a service discovery request.") 605 public void wifiP2pRemoveServiceRequest(@RpcParameter(name = "index") Integer index) { 606 mP2p.removeServiceRequest(mChannel, mServiceRequests.remove(index), 607 new WifiP2pActionListener(mEventFacade, "RemoveServiceRequest")); 608 } 609 610 @Rpc(description = "Request device connection info.") 611 public void wifiP2pRequestConnectionInfo() { 612 mP2p.requestConnectionInfo(mChannel, new WifiP2pConnectionInfoListener(mEventFacade)); 613 } 614 615 @Rpc(description = "Create a wifi p2p group.") 616 public void wifiP2pRequestGroupInfo() { 617 mP2p.requestGroupInfo(mChannel, new WifiP2pGroupInfoListener(mEventFacade)); 618 } 619 620 @Rpc(description = "Request peers that are discovered for wifi p2p.") 621 public void wifiP2pRequestPeers() { 622 mP2p.requestPeers(mChannel, new WifiP2pPeerListListener(mEventFacade)); 623 } 624 625 @Rpc(description = "Request a list of all the persistent p2p groups stored in system.") 626 public void wifiP2pRequestPersistentGroupInfo() { 627 mP2p.requestPersistentGroupInfo(mChannel, 628 new WifiP2pPersistentGroupInfoListener(mEventFacade)); 629 } 630 631 @Rpc(description = "Set p2p device name.") 632 public void wifiP2pSetDeviceName(@RpcParameter(name = "devName") String devName) { 633 mP2p.setDeviceName(mChannel, devName, 634 new WifiP2pActionListener(mEventFacade, "SetDeviceName")); 635 } 636 637 @Rpc(description = "Register a callback to be invoked on receiving Bonjour service discovery response.") 638 public void wifiP2pSetDnsSdResponseListeners() { 639 mP2p.setDnsSdResponseListeners(mChannel, 640 new WifiP2pDnsSdServiceResponseListener(mEventFacade), 641 new WifiP2pDnsSdTxtRecordListener(mEventFacade)); 642 } 643 644 /** 645 * Register a callback to be invoked on receiving 646 * Upnp service discovery response. 647 */ 648 @Rpc(description = "Register a callback to be invoked on receiving " 649 + "Upnp service discovery response.") 650 public void wifiP2pSetUpnpResponseListeners() { 651 mP2p.setUpnpServiceResponseListener(mChannel, 652 new WifiP2pUpnpServiceResponseListener(mEventFacade)); 653 } 654 655 @Rpc(description = "Stop an ongoing peer discovery.") 656 public void wifiP2pStopPeerDiscovery() { 657 mP2p.stopPeerDiscovery(mChannel, 658 new WifiP2pActionListener(mEventFacade, "StopPeerDiscovery")); 659 } 660 661 private WpsInfo genWpsInfo(JSONObject j) throws JSONException { 662 if (j == null) { 663 return null; 664 } 665 WpsInfo wpsInfo = new WpsInfo(); 666 if (j.has("setup")) { 667 wpsInfo.setup = j.getInt("setup"); 668 } 669 if (j.has("BSSID")) { 670 wpsInfo.BSSID = j.getString("BSSID"); 671 } 672 if (j.has("pin")) { 673 wpsInfo.pin = j.getString("pin"); 674 } 675 return wpsInfo; 676 } 677 678 private WifiP2pConfig genWifiP2pConfig(JSONObject j) throws JSONException, 679 NumberFormatException { 680 if (j == null) { 681 return null; 682 } 683 WifiP2pConfig config = new WifiP2pConfig(); 684 if (j.has("networkName") && j.has("passphrase")) { 685 WifiP2pConfig.Builder b = new WifiP2pConfig.Builder(); 686 b.setNetworkName(j.getString("networkName")); 687 b.setPassphrase(j.getString("passphrase")); 688 if (j.has("groupOwnerBand")) { 689 b.setGroupOperatingBand(Integer.parseInt(j.getString("groupOwnerBand"))); 690 } 691 config = b.build(); 692 } 693 if (j.has("deviceAddress")) { 694 config.deviceAddress = j.getString("deviceAddress"); 695 } 696 if (j.has("wpsInfo")) { 697 config.wps = genWpsInfo(j.getJSONObject("wpsInfo")); 698 } 699 if (j.has("groupOwnerIntent")) { 700 config.groupOwnerIntent = j.getInt("groupOwnerIntent"); 701 } 702 if (j.has("netId")) { 703 config.netId = j.getInt("netId"); 704 } 705 return config; 706 } 707 708 /** 709 * Set saved WifiP2pConfig for an ongoing peer connection 710 * @param wifiP2pConfig JSONObject Dictionary of p2p connection parameters 711 * @throws JSONException 712 */ 713 @Rpc(description = "Set saved WifiP2pConfig for an ongoing peer connection") 714 public void setP2pPeerConfigure(@RpcParameter(name = "config") JSONObject wifiP2pConfig) 715 throws JSONException { 716 mP2p.setOngoingPeerConfig(mChannel, genWifiP2pConfig(wifiP2pConfig), 717 new WifiP2pActionListener(mEventFacade, "setP2pPeerConfigure")); 718 } 719 720 /** 721 * Request saved WifiP2pConfig which used for an ongoing peer connection 722 */ 723 @Rpc(description = "Request saved WifiP2pConfig which used for an ongoing peer connection") 724 public void requestP2pPeerConfigure() { 725 mP2p.requestOngoingPeerConfig(mChannel, new WifiP2pOngoingPeerConfigListener(mEventFacade)); 726 } 727 } 728