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 */ 16package com.android.networkrecommendation.util; 17 18import static com.android.networkrecommendation.Constants.TAG; 19import static com.android.networkrecommendation.util.SsidUtil.quoteSsid; 20 21import android.net.NetworkKey; 22import android.net.WifiKey; 23import android.net.wifi.ScanResult; 24import android.net.wifi.WifiConfiguration; 25import android.support.annotation.Nullable; 26import android.text.TextUtils; 27import com.android.networkrecommendation.config.G; 28 29/** 30 * Scan result utility for any {@link ScanResult} related operations. TODO(b/34125341): Delete this 31 * class once exposed as a SystemApi 32 */ 33public class ScanResultUtil { 34 35 /** 36 * Helper method to check if the provided |scanResult| corresponds to a PSK network or not. This 37 * checks if the provided capabilities string contains PSK encryption type or not. 38 */ 39 public static boolean isScanResultForPskNetwork(ScanResult scanResult) { 40 return scanResult.capabilities.contains("PSK"); 41 } 42 43 /** 44 * Helper method to check if the provided |scanResult| corresponds to a EAP network or not. This 45 * checks if the provided capabilities string contains EAP encryption type or not. 46 */ 47 public static boolean isScanResultForEapNetwork(ScanResult scanResult) { 48 return scanResult.capabilities.contains("EAP"); 49 } 50 51 /** 52 * Helper method to check if the provided |scanResult| corresponds to a WEP network or not. This 53 * checks if the provided capabilities string contains WEP encryption type or not. 54 */ 55 public static boolean isScanResultForWepNetwork(ScanResult scanResult) { 56 return scanResult.capabilities.contains("WEP"); 57 } 58 59 /** 60 * Helper method to check if the provided |scanResult| corresponds to an open network or not. 61 * This checks if the provided capabilities string does not contain either of WEP, PSK or EAP 62 * encryption types or not. 63 */ 64 public static boolean isScanResultForOpenNetwork(ScanResult scanResult) { 65 return !(isScanResultForWepNetwork(scanResult) 66 || isScanResultForPskNetwork(scanResult) 67 || isScanResultForEapNetwork(scanResult)); 68 } 69 70 /** Create a {@link NetworkKey} from a ScanResult, properly quoting the SSID. */ 71 @Nullable 72 public static final NetworkKey createNetworkKey(ScanResult scanResult) { 73 WifiKey wifiKey = createWifiKey(scanResult); 74 if (wifiKey == null) { 75 return null; 76 } 77 return new NetworkKey(wifiKey); 78 } 79 80 /** 81 * Helper method to quote the SSID in Scan result to use for comparing/filling SSID stored in 82 * WifiConfiguration object. 83 */ 84 @Nullable 85 public static WifiKey createWifiKey(ScanResult result) { 86 if (result == null) { 87 Blog.e(TAG, "Couldn't create WifiKey, provided scan result is null."); 88 return null; 89 } 90 try { 91 return new WifiKey(quoteSsid(result.SSID), result.BSSID); 92 } catch (IllegalArgumentException | NullPointerException e) { 93 // Expect IllegalArgumentException only in Android O. 94 Blog.e( 95 TAG, 96 e, 97 "Couldn't make a wifi key from %s/%s", 98 Blog.pii(result.SSID, G.Netrec.enableSensitiveLogging.get()), 99 Blog.pii(result.BSSID, G.Netrec.enableSensitiveLogging.get())); 100 return null; 101 } 102 } 103 104 /** @return {@code true} if the result is for a 2.4GHz network. */ 105 public static boolean is24GHz(ScanResult result) { 106 return is24GHz(result.frequency); 107 } 108 109 /** @return {@code true} if the frequency is for a 2.4GHz network. */ 110 public static boolean is24GHz(int freq) { 111 return freq > 2400 && freq < 2500; 112 } 113 114 /** @return {@code true} if the result is for a 5GHz network. */ 115 public static boolean is5GHz(ScanResult result) { 116 return is5GHz(result.frequency); 117 } 118 119 /** @return {@code true} if the frequency is for a 5GHz network. */ 120 public static boolean is5GHz(int freq) { 121 return freq > 4900 && freq < 5900; 122 } 123 124 /** 125 * Checks if the provided |scanResult| match with the provided |config|. Essentially checks if 126 * the network config and scan result have the same SSID and encryption type. 127 */ 128 public static boolean doesScanResultMatchWithNetwork( 129 ScanResult scanResult, WifiConfiguration config) { 130 // Add the double quotes to the scan result SSID for comparison with the network configs. 131 String configSSID = quoteSsid(scanResult.SSID); 132 if (TextUtils.equals(config.SSID, configSSID)) { 133 if (ScanResultUtil.isScanResultForPskNetwork(scanResult) 134 && WifiConfigurationUtil.isConfigForPskNetwork(config)) { 135 return true; 136 } 137 if (ScanResultUtil.isScanResultForEapNetwork(scanResult) 138 && WifiConfigurationUtil.isConfigForEapNetwork(config)) { 139 return true; 140 } 141 if (ScanResultUtil.isScanResultForWepNetwork(scanResult) 142 && WifiConfigurationUtil.isConfigForWepNetwork(config)) { 143 return true; 144 } 145 if (ScanResultUtil.isScanResultForOpenNetwork(scanResult) 146 && WifiConfigurationUtil.isConfigForOpenNetwork(config)) { 147 return true; 148 } 149 } 150 return false; 151 } 152} 153