1 package com.android.hotspot2.flow; 2 3 import android.content.Context; 4 import android.content.Intent; 5 import android.net.Network; 6 import android.net.wifi.PasspointManagementObjectDefinition; 7 import android.net.wifi.WifiConfiguration; 8 import android.net.wifi.WifiEnterpriseConfig; 9 import android.net.wifi.WifiInfo; 10 import android.net.wifi.WifiManager; 11 import android.util.Log; 12 13 import com.android.configparse.ConfigBuilder; 14 import com.android.hotspot2.AppBridge; 15 import com.android.hotspot2.Utils; 16 import com.android.hotspot2.app.OSUService; 17 import com.android.hotspot2.omadm.MOManager; 18 import com.android.hotspot2.omadm.MOTree; 19 import com.android.hotspot2.omadm.OMAConstants; 20 import com.android.hotspot2.omadm.OMAException; 21 import com.android.hotspot2.omadm.OMAParser; 22 import com.android.hotspot2.osu.ClientKeyManager; 23 import com.android.hotspot2.osu.OSUCertType; 24 import com.android.hotspot2.osu.OSUManager; 25 import com.android.hotspot2.osu.OSUOperationStatus; 26 import com.android.hotspot2.osu.OSUSocketFactory; 27 import com.android.hotspot2.osu.WiFiKeyManager; 28 import com.android.hotspot2.osu.commands.MOData; 29 import com.android.hotspot2.pps.HomeSP; 30 31 import org.xml.sax.SAXException; 32 33 import java.io.File; 34 import java.io.FileInputStream; 35 import java.io.FileOutputStream; 36 import java.io.IOException; 37 import java.security.GeneralSecurityException; 38 import java.security.KeyStore; 39 import java.security.KeyStoreException; 40 import java.security.PrivateKey; 41 import java.security.cert.Certificate; 42 import java.security.cert.X509Certificate; 43 import java.util.ArrayList; 44 import java.util.Collection; 45 import java.util.Enumeration; 46 import java.util.HashMap; 47 import java.util.Iterator; 48 import java.util.List; 49 import java.util.Locale; 50 import java.util.Map; 51 import java.util.Set; 52 53 import javax.net.ssl.KeyManager; 54 55 public class PlatformAdapter { 56 private static final String TAG = "OSUFLOW"; 57 58 public static final Locale LOCALE = Locale.getDefault(); 59 60 public static final String CERT_WFA_ALIAS = "wfa-root-"; 61 public static final String CERT_REM_ALIAS = "rem-"; 62 public static final String CERT_POLICY_ALIAS = "pol-"; 63 public static final String CERT_SHARED_ALIAS = "shr-"; 64 public static final String CERT_CLT_CERT_ALIAS = "clt-"; 65 public static final String CERT_CLT_KEY_ALIAS = "prv-"; 66 public static final String CERT_CLT_CA_ALIAS = "aaa-"; 67 68 private static final String KEYSTORE_FILE = "passpoint.ks"; 69 70 private final Context mContext; 71 private final File mKeyStoreFile; 72 private final KeyStore mKeyStore; 73 private final AppBridge mAppBridge; 74 private final Map<String, PasspointConfig> mPasspointConfigs; 75 PlatformAdapter(Context context)76 public PlatformAdapter(Context context) { 77 mContext = context; 78 mAppBridge = new AppBridge(context); 79 80 File appFolder = context.getFilesDir(); 81 mKeyStoreFile = new File(appFolder, KEYSTORE_FILE); 82 Log.d(TAG, "KS file: " + mKeyStoreFile.getPath()); 83 KeyStore ks = null; 84 try { 85 //ks = loadKeyStore(KEYSTORE_FILE, readCertsFromDisk(WFA_CA_LOC)); 86 ks = loadKeyStore(mKeyStoreFile, OSUSocketFactory.buildCertSet()); 87 } catch (IOException e) { 88 Log.e(TAG, "Failed to initialize Passpoint keystore, OSU disabled", e); 89 } 90 mKeyStore = ks; 91 92 mPasspointConfigs = loadAllSps(context); 93 } 94 loadKeyStore(File ksFile, Set<X509Certificate> diskCerts)95 private static KeyStore loadKeyStore(File ksFile, Set<X509Certificate> diskCerts) 96 throws IOException { 97 try { 98 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 99 if (ksFile.exists()) { 100 try (FileInputStream in = new FileInputStream(ksFile)) { 101 keyStore.load(in, null); 102 } 103 104 // Note: comparing two sets of certs does not work. 105 boolean mismatch = false; 106 int loadCount = 0; 107 for (int n = 0; n < 1000; n++) { 108 String alias = String.format("%s%d", CERT_WFA_ALIAS, n); 109 Certificate cert = keyStore.getCertificate(alias); 110 if (cert == null) { 111 break; 112 } 113 114 loadCount++; 115 boolean matched = false; 116 Iterator<X509Certificate> iter = diskCerts.iterator(); 117 while (iter.hasNext()) { 118 X509Certificate diskCert = iter.next(); 119 if (cert.equals(diskCert)) { 120 iter.remove(); 121 matched = true; 122 break; 123 } 124 } 125 if (!matched) { 126 mismatch = true; 127 break; 128 } 129 } 130 if (mismatch || !diskCerts.isEmpty()) { 131 Log.d(TAG, "Re-seeding Passpoint key store with " + 132 diskCerts.size() + " WFA certs"); 133 for (int n = 0; n < 1000; n++) { 134 String alias = String.format("%s%d", CERT_WFA_ALIAS, n); 135 Certificate cert = keyStore.getCertificate(alias); 136 if (cert == null) { 137 break; 138 } else { 139 keyStore.deleteEntry(alias); 140 } 141 } 142 int index = 0; 143 for (X509Certificate caCert : diskCerts) { 144 keyStore.setCertificateEntry( 145 String.format("%s%d", CERT_WFA_ALIAS, index), caCert); 146 index++; 147 } 148 149 try (FileOutputStream out = new FileOutputStream(ksFile)) { 150 keyStore.store(out, null); 151 } 152 } else { 153 Log.d(TAG, "Loaded Passpoint key store with " + loadCount + " CA certs"); 154 Enumeration<String> aliases = keyStore.aliases(); 155 while (aliases.hasMoreElements()) { 156 Log.d("ZXC", "KS Alias '" + aliases.nextElement() + "'"); 157 } 158 } 159 } else { 160 keyStore.load(null, null); 161 int index = 0; 162 for (X509Certificate caCert : diskCerts) { 163 keyStore.setCertificateEntry( 164 String.format("%s%d", CERT_WFA_ALIAS, index), caCert); 165 index++; 166 } 167 168 try (FileOutputStream out = new FileOutputStream(ksFile)) { 169 keyStore.store(out, null); 170 } 171 Log.d(TAG, "Initialized Passpoint key store with " + 172 diskCerts.size() + " CA certs"); 173 } 174 return keyStore; 175 } catch (GeneralSecurityException gse) { 176 throw new IOException(gse); 177 } 178 } 179 loadAllSps(Context context)180 private static Map<String, PasspointConfig> loadAllSps(Context context) { 181 Map<String, PasspointConfig> passpointConfigs = new HashMap<>(); 182 183 WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 184 List<WifiConfiguration> configs = wifiManager.getPrivilegedConfiguredNetworks(); 185 if (configs == null) { 186 return passpointConfigs; 187 } 188 int count = 0; 189 for (WifiConfiguration config : configs) { 190 String moTree = config.getMoTree(); 191 if (moTree != null) { 192 try { 193 passpointConfigs.put(config.FQDN, new PasspointConfig(config)); 194 count++; 195 } catch (IOException | SAXException e) { 196 Log.w(OSUManager.TAG, "Failed to parse MO: " + e); 197 } 198 } 199 } 200 Log.d(OSUManager.TAG, "Loaded " + count + " SPs"); 201 return passpointConfigs; 202 } 203 getKeyStore()204 public KeyStore getKeyStore() { 205 return mKeyStore; 206 } 207 getContext()208 public Context getContext() { 209 return mContext; 210 } 211 212 /** 213 * Connect to an OSU provisioning network. The connection should not bring down other existing 214 * connection and the network should not be made the default network since the connection 215 * is solely for sign up and is neither intended for nor likely provides access to any 216 * generic resources. 217 * 218 * @param osuInfo The OSU info object that defines the parameters for the network. An OSU 219 * network is either an open network, or, if the OSU NAI is set, an "OSEN" 220 * network, which is an anonymous EAP-TLS network with special keys. 221 * @return an Integer holding the network-id of the just added network configuration, or null 222 * if the network existed prior to this call (was not added by the OSU infrastructure). 223 * The value will be used at the end of the OSU flow to delete the network as applicable. 224 * @throws IOException Issues: 225 * 1. The network id is not returned. addNetwork cannot be called from here since the method 226 * runs in the context of the app and doesn't have the appropriate permission. 227 * 2. The connection is not immediately usable if the network was not previously selected 228 * manually. 229 */ connect(OSUInfo osuInfo)230 public Integer connect(OSUInfo osuInfo) throws IOException { 231 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 232 233 WifiConfiguration config = new WifiConfiguration(); 234 config.SSID = '"' + osuInfo.getOsuSsid() + '"'; 235 if (osuInfo.getOSUBssid() != 0) { 236 config.BSSID = Utils.macToString(osuInfo.getOSUBssid()); 237 Log.d(OSUManager.TAG, String.format("Setting BSSID of '%s' to %012x", 238 osuInfo.getOsuSsid(), osuInfo.getOSUBssid())); 239 } 240 241 if (osuInfo.getOSUProvider().getOsuNai() == null) { 242 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); 243 } else { 244 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OSEN); 245 config.allowedProtocols.set(WifiConfiguration.Protocol.OSEN); 246 config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); 247 config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GTK_NOT_USED); 248 config.enterpriseConfig = new WifiEnterpriseConfig(); 249 config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.UNAUTH_TLS); 250 config.enterpriseConfig.setIdentity(osuInfo.getOSUProvider().getOsuNai()); 251 Set<X509Certificate> cas = OSUSocketFactory.buildCertSet(); 252 config.enterpriseConfig.setCaCertificates(cas.toArray(new X509Certificate[cas.size()])); 253 } 254 255 int networkId = wifiManager.addNetwork(config); 256 if (networkId < 0) { 257 throw new IOException("Failed to add OSU network"); 258 } 259 if (wifiManager.enableNetwork(networkId, true)) { 260 return networkId; 261 } else { 262 throw new IOException("Failed to enable OSU network"); 263 } 264 } 265 266 /** 267 * @param homeSP The Home SP associated with the keying material in question. Passing 268 * null returns a "system wide" KeyManager to support pre-provisioned certs based 269 * on names retrieved from the ClientCertInfo request. 270 * @return A key manager suitable for the given configuration (or pre-provisioned keys). 271 */ getKeyManager(HomeSP homeSP)272 public KeyManager getKeyManager(HomeSP homeSP) throws IOException { 273 return homeSP != null 274 ? new ClientKeyManager(homeSP, mKeyStore) : new WiFiKeyManager(mKeyStore); 275 } 276 provisioningComplete(OSUInfo osuInfo, MOData moData, Map<OSUCertType, List<X509Certificate>> certs, PrivateKey privateKey, Network osuNetwork)277 public void provisioningComplete(OSUInfo osuInfo, 278 MOData moData, Map<OSUCertType, List<X509Certificate>> certs, 279 PrivateKey privateKey, Network osuNetwork) { 280 try { 281 String xml = moData.getMOTree().toXml(); 282 HomeSP homeSP = MOManager.buildSP(xml); 283 284 Integer spNwk = addNetwork(homeSP, certs, privateKey, osuNetwork); 285 if (spNwk == null) { 286 notifyUser(OSUOperationStatus.ProvisioningFailure, 287 "Failed to save network configuration", osuInfo.getName(LOCALE)); 288 } else { 289 if (addSP(xml) < 0) { 290 deleteNetwork(spNwk); 291 Log.e(TAG, "Failed to provision: " + homeSP.getFQDN()); 292 notifyUser(OSUOperationStatus.ProvisioningFailure, "Failed to add MO", 293 osuInfo.getName(LOCALE)); 294 return; 295 } 296 Set<X509Certificate> rootCerts = OSUSocketFactory.getRootCerts(mKeyStore); 297 X509Certificate remCert = getCert(certs, OSUCertType.Remediation); 298 X509Certificate polCert = getCert(certs, OSUCertType.Policy); 299 int newCerts = 0; 300 if (privateKey != null) { 301 X509Certificate cltCert = getCert(certs, OSUCertType.Client); 302 mKeyStore.setKeyEntry(CERT_CLT_KEY_ALIAS + homeSP.getFQDN(), 303 privateKey, null, new X509Certificate[]{cltCert}); 304 mKeyStore.setCertificateEntry(CERT_CLT_CERT_ALIAS + homeSP.getFQDN(), cltCert); 305 newCerts++; 306 } 307 boolean usingShared = false; 308 if (remCert != null) { 309 if (!rootCerts.contains(remCert)) { 310 if (remCert.equals(polCert)) { 311 mKeyStore.setCertificateEntry(CERT_SHARED_ALIAS + homeSP.getFQDN(), 312 remCert); 313 usingShared = true; 314 newCerts++; 315 } else { 316 mKeyStore.setCertificateEntry(CERT_REM_ALIAS + homeSP.getFQDN(), 317 remCert); 318 newCerts++; 319 } 320 } 321 } 322 if (!usingShared && polCert != null) { 323 if (!rootCerts.contains(polCert)) { 324 mKeyStore.setCertificateEntry(CERT_POLICY_ALIAS + homeSP.getFQDN(), 325 remCert); 326 newCerts++; 327 } 328 } 329 330 331 if (newCerts > 0) { 332 try (FileOutputStream out = new FileOutputStream(mKeyStoreFile)) { 333 mKeyStore.store(out, null); 334 } 335 } 336 notifyUser(OSUOperationStatus.ProvisioningSuccess, null, osuInfo.getName(LOCALE)); 337 Log.d(TAG, "Provisioning complete."); 338 } 339 } catch (IOException | GeneralSecurityException | SAXException e) { 340 Log.e(TAG, "Failed to provision: " + e, e); 341 notifyUser(OSUOperationStatus.ProvisioningFailure, e.toString(), 342 osuInfo.getName(LOCALE)); 343 } 344 } 345 remediationComplete(HomeSP homeSP, Collection<MOData> mods, Map<OSUCertType, List<X509Certificate>> certs, PrivateKey privateKey, boolean policy)346 public void remediationComplete(HomeSP homeSP, Collection<MOData> mods, 347 Map<OSUCertType, List<X509Certificate>> certs, 348 PrivateKey privateKey, boolean policy) 349 throws IOException, GeneralSecurityException { 350 351 HomeSP altSP = null; 352 if (modifySP(homeSP, mods) > 0) { 353 altSP = MOManager.modifySP(homeSP, getMOTree(homeSP), mods); 354 } 355 356 X509Certificate caCert = null; 357 List<X509Certificate> clientCerts = null; 358 if (certs != null) { 359 List<X509Certificate> certList = certs.get(OSUCertType.AAA); 360 caCert = certList != null && !certList.isEmpty() ? certList.iterator().next() : null; 361 clientCerts = certs.get(OSUCertType.Client); 362 } 363 if (altSP != null || certs != null) { 364 if (altSP == null) { 365 altSP = homeSP; 366 } 367 updateNetwork(altSP, caCert, clientCerts, privateKey); 368 369 if (privateKey != null) { 370 X509Certificate cltCert = getCert(certs, OSUCertType.Client); 371 mKeyStore.setKeyEntry(CERT_CLT_KEY_ALIAS + homeSP.getFQDN(), 372 privateKey, null, new X509Certificate[]{cltCert}); 373 mKeyStore.setCertificateEntry(CERT_CLT_CERT_ALIAS + homeSP.getFQDN(), cltCert); 374 } 375 } 376 377 Intent intent = new Intent(OSUService.REMEDIATION_DONE_ACTION); 378 intent.putExtra(OSUService.REMEDIATION_FQDN_EXTRA, homeSP.getFQDN()); 379 intent.putExtra(OSUService.REMEDIATION_POLICY_EXTRA, policy); 380 mContext.sendBroadcast(intent); 381 382 notifyUser(OSUOperationStatus.ProvisioningSuccess, null, homeSP.getFriendlyName()); 383 } 384 serviceProviderDeleted(String fqdn)385 public void serviceProviderDeleted(String fqdn) { 386 int count = deleteCerts(mKeyStore, fqdn, 387 CERT_REM_ALIAS, CERT_POLICY_ALIAS, CERT_SHARED_ALIAS, CERT_CLT_CERT_ALIAS); 388 389 Log.d(TAG, "Passpoint network deleted, removing " + count + " key store entries"); 390 391 try { 392 if (mKeyStore.getKey(CERT_CLT_KEY_ALIAS + fqdn, null) != null) { 393 mKeyStore.deleteEntry(CERT_CLT_KEY_ALIAS + fqdn); 394 } 395 } catch (GeneralSecurityException e) { 396 /**/ 397 } 398 399 if (count > 0) { 400 try (FileOutputStream out = new FileOutputStream(mKeyStoreFile)) { 401 mKeyStore.store(out, null); 402 } catch (IOException | GeneralSecurityException e) { 403 Log.w(TAG, "Failed to remove certs from key store: " + e); 404 } 405 } 406 } 407 deleteCerts(KeyStore keyStore, String fqdn, String... prefixes)408 private static int deleteCerts(KeyStore keyStore, String fqdn, String... prefixes) { 409 int count = 0; 410 for (String prefix : prefixes) { 411 try { 412 String alias = prefix + fqdn; 413 Certificate cert = keyStore.getCertificate(alias); 414 if (cert != null) { 415 keyStore.deleteEntry(alias); 416 count++; 417 } 418 } catch (KeyStoreException kse) { 419 /**/ 420 } 421 } 422 return count; 423 } 424 getCert(Map<OSUCertType, List<X509Certificate>> certMap, OSUCertType certType)425 private static X509Certificate getCert(Map<OSUCertType, List<X509Certificate>> certMap, 426 OSUCertType certType) { 427 List<X509Certificate> certs = certMap.get(certType); 428 if (certs == null || certs.isEmpty()) { 429 return null; 430 } 431 return certs.iterator().next(); 432 } 433 notifyUser(OSUOperationStatus status, String message, String spName)434 public String notifyUser(OSUOperationStatus status, String message, String spName) { 435 if (status == OSUOperationStatus.UserInputComplete) { 436 return null; 437 } 438 mAppBridge.showStatus(status, spName, message, null); 439 return null; 440 } 441 provisioningFailed(String spName, String message)442 public void provisioningFailed(String spName, String message) { 443 notifyUser(OSUOperationStatus.ProvisioningFailure, message, spName); 444 } 445 addNetwork(HomeSP homeSP, Map<OSUCertType, List<X509Certificate>> certs, PrivateKey privateKey, Network osuNetwork)446 private Integer addNetwork(HomeSP homeSP, Map<OSUCertType, List<X509Certificate>> certs, 447 PrivateKey privateKey, Network osuNetwork) 448 throws IOException, GeneralSecurityException { 449 450 List<X509Certificate> aaaTrust = certs.get(OSUCertType.AAA); 451 if (aaaTrust.isEmpty()) { 452 aaaTrust = certs.get(OSUCertType.CA); // Get the CAs from the EST flow. 453 } 454 455 WifiConfiguration config = ConfigBuilder.buildConfig(homeSP, 456 aaaTrust.iterator().next(), 457 certs.get(OSUCertType.Client), privateKey); 458 459 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 460 int nwkId = wifiManager.addNetwork(config); 461 boolean saved = false; 462 if (nwkId >= 0) { 463 saved = wifiManager.saveConfiguration(); 464 } 465 Log.d(OSUManager.TAG, "Wifi configuration " + nwkId + 466 " " + (saved ? "saved" : "not saved")); 467 468 if (saved) { 469 reconnect(osuNetwork, nwkId); 470 return nwkId; 471 } else { 472 return null; 473 } 474 } 475 updateNetwork(HomeSP homeSP, X509Certificate caCert, List<X509Certificate> clientCerts, PrivateKey privateKey)476 private void updateNetwork(HomeSP homeSP, X509Certificate caCert, 477 List<X509Certificate> clientCerts, PrivateKey privateKey) 478 throws IOException, GeneralSecurityException { 479 480 WifiConfiguration config = getWifiConfig(homeSP); 481 if (config == null) { 482 throw new IOException("Failed to find matching network config"); 483 } 484 Log.d(OSUManager.TAG, "Found matching config " + config.networkId + ", updating"); 485 486 WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig; 487 WifiConfiguration newConfig = ConfigBuilder.buildConfig(homeSP, 488 caCert != null ? caCert : enterpriseConfig.getCaCertificate(), 489 clientCerts, privateKey); 490 newConfig.networkId = config.networkId; 491 492 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 493 wifiManager.save(newConfig, null); 494 wifiManager.saveConfiguration(); 495 } 496 getWifiConfig(HomeSP homeSP)497 private WifiConfiguration getWifiConfig(HomeSP homeSP) { 498 PasspointConfig passpointConfig = mPasspointConfigs.get(homeSP.getFQDN()); 499 return passpointConfig != null ? passpointConfig.getWifiConfiguration() : null; 500 } 501 getMOTree(HomeSP homeSP)502 public MOTree getMOTree(HomeSP homeSP) { 503 PasspointConfig config = mPasspointConfigs.get(homeSP.getFQDN()); 504 return config != null ? config.getmMOTree() : null; 505 } 506 getHomeSP(String fqdn)507 public HomeSP getHomeSP(String fqdn) { 508 PasspointConfig passpointConfig = mPasspointConfigs.get(fqdn); 509 return passpointConfig != null ? passpointConfig.getHomeSP() : null; 510 } 511 getCurrentSP()512 public HomeSP getCurrentSP() { 513 PasspointConfig passpointConfig = getActivePasspointConfig(); 514 return passpointConfig != null ? passpointConfig.getHomeSP() : null; 515 } 516 getActivePasspointConfig()517 private PasspointConfig getActivePasspointConfig() { 518 WifiInfo wifiInfo = getConnectionInfo(); 519 if (wifiInfo == null) { 520 return null; 521 } 522 523 for (PasspointConfig passpointConfig : mPasspointConfigs.values()) { 524 if (passpointConfig.getWifiConfiguration().networkId == wifiInfo.getNetworkId()) { 525 return passpointConfig; 526 } 527 } 528 return null; 529 } 530 addSP(String xml)531 private int addSP(String xml) throws IOException, SAXException { 532 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 533 // TODO(b/32883320): use the new API for adding Passpoint configuration. 534 return 0; 535 } 536 modifySP(HomeSP homeSP, Collection<MOData> mods)537 private int modifySP(HomeSP homeSP, Collection<MOData> mods) throws IOException { 538 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 539 List<PasspointManagementObjectDefinition> defMods = new ArrayList<>(mods.size()); 540 for (MOData mod : mods) { 541 defMods.add(new PasspointManagementObjectDefinition(mod.getBaseURI(), 542 mod.getURN(), mod.getMOTree().toXml())); 543 } 544 // TODO(b/32883320): use the new API to update Passpoint configuration. 545 return 0; 546 } 547 reconnect(Network osuNetwork, int newNwkId)548 private void reconnect(Network osuNetwork, int newNwkId) { 549 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 550 if (osuNetwork != null) { 551 wifiManager.disableNetwork(osuNetwork.netId); 552 } 553 if (newNwkId != WifiConfiguration.INVALID_NETWORK_ID) { 554 wifiManager.enableNetwork(newNwkId, true); 555 } 556 } 557 deleteNetwork(int id)558 public void deleteNetwork(int id) { 559 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 560 wifiManager.disableNetwork(id); 561 wifiManager.forget(id, null); 562 } 563 getConnectionInfo()564 public WifiInfo getConnectionInfo() { 565 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 566 return wifiManager.getConnectionInfo(); 567 } 568 getCurrentNetwork()569 public Network getCurrentNetwork() { 570 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 571 return wifiManager.getCurrentNetwork(); 572 } 573 getActiveWifiConfig()574 public WifiConfiguration getActiveWifiConfig() { 575 WifiInfo wifiInfo = getConnectionInfo(); 576 if (wifiInfo == null) { 577 return null; 578 } 579 WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 580 List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks(); 581 if (configs == null) { 582 return null; 583 } 584 for (WifiConfiguration config : configs) { 585 if (config.networkId == wifiInfo.getNetworkId()) { 586 return config; 587 } 588 } 589 return null; 590 } 591 592 private static class PasspointConfig { 593 private final WifiConfiguration mWifiConfiguration; 594 private final MOTree mMOTree; 595 private final HomeSP mHomeSP; 596 PasspointConfig(WifiConfiguration config)597 private PasspointConfig(WifiConfiguration config) throws IOException, SAXException { 598 mWifiConfiguration = config; 599 OMAParser omaParser = new OMAParser(); 600 mMOTree = omaParser.parse(config.getMoTree(), OMAConstants.PPS_URN); 601 List<HomeSP> spList = MOManager.buildSPs(mMOTree); 602 if (spList.size() != 1) { 603 throw new OMAException("Expected exactly one HomeSP, got " + spList.size()); 604 } 605 mHomeSP = spList.iterator().next(); 606 } 607 getWifiConfiguration()608 public WifiConfiguration getWifiConfiguration() { 609 return mWifiConfiguration; 610 } 611 getHomeSP()612 public HomeSP getHomeSP() { 613 return mHomeSP; 614 } 615 getmMOTree()616 public MOTree getmMOTree() { 617 return mMOTree; 618 } 619 } 620 } 621