/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.wifi; import android.annotation.SystemApi; import android.content.pm.PackageManager; import android.net.IpConfiguration; import android.net.IpConfiguration.ProxySettings; import android.net.ProxyInfo; import android.net.StaticIpConfiguration; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; import android.text.TextUtils; import android.util.BackupUtils; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.BitSet; import java.util.HashMap; /** * A class representing a configured Wi-Fi network, including the * security configuration. */ public class WifiConfiguration implements Parcelable { private static final String TAG = "WifiConfiguration"; /** * Current Version of the Backup Serializer. */ private static final int BACKUP_VERSION = 2; /** {@hide} */ public static final String ssidVarName = "ssid"; /** {@hide} */ public static final String bssidVarName = "bssid"; /** {@hide} */ public static final String pskVarName = "psk"; /** {@hide} */ public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" }; /** {@hide} */ public static final String wepTxKeyIdxVarName = "wep_tx_keyidx"; /** {@hide} */ public static final String priorityVarName = "priority"; /** {@hide} */ public static final String hiddenSSIDVarName = "scan_ssid"; /** {@hide} */ public static final String pmfVarName = "ieee80211w"; /** {@hide} */ public static final String updateIdentiferVarName = "update_identifier"; /** {@hide} */ public static final int INVALID_NETWORK_ID = -1; /** {@hide} */ private String mPasspointManagementObjectTree; /** * Recognized key management schemes. */ public static class KeyMgmt { private KeyMgmt() { } /** WPA is not used; plaintext or static WEP could be used. */ public static final int NONE = 0; /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */ public static final int WPA_PSK = 1; /** WPA using EAP authentication. Generally used with an external authentication server. */ public static final int WPA_EAP = 2; /** IEEE 802.1X using EAP authentication and (optionally) dynamically * generated WEP keys. */ public static final int IEEE8021X = 3; /** WPA2 pre-shared key for use with soft access point * (requires {@code preSharedKey} to be specified). * @hide */ @SystemApi public static final int WPA2_PSK = 4; /** * Hotspot 2.0 r2 OSEN: * @hide */ public static final int OSEN = 5; public static final String varName = "key_mgmt"; public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X", "WPA2_PSK", "OSEN" }; } /** * Recognized security protocols. */ public static class Protocol { private Protocol() { } /** WPA/IEEE 802.11i/D3.0 */ public static final int WPA = 0; /** WPA2/IEEE 802.11i */ public static final int RSN = 1; /** HS2.0 r2 OSEN * @hide */ public static final int OSEN = 2; public static final String varName = "proto"; public static final String[] strings = { "WPA", "RSN", "OSEN" }; } /** * Recognized IEEE 802.11 authentication algorithms. */ public static class AuthAlgorithm { private AuthAlgorithm() { } /** Open System authentication (required for WPA/WPA2) */ public static final int OPEN = 0; /** Shared Key authentication (requires static WEP keys) */ public static final int SHARED = 1; /** LEAP/Network EAP (only used with LEAP) */ public static final int LEAP = 2; public static final String varName = "auth_alg"; public static final String[] strings = { "OPEN", "SHARED", "LEAP" }; } /** * Recognized pairwise ciphers for WPA. */ public static class PairwiseCipher { private PairwiseCipher() { } /** Use only Group keys (deprecated) */ public static final int NONE = 0; /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ public static final int TKIP = 1; /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ public static final int CCMP = 2; public static final String varName = "pairwise"; public static final String[] strings = { "NONE", "TKIP", "CCMP" }; } /** * Recognized group ciphers. *
* CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) **/ public static class GroupCipher { private GroupCipher() { } /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) */ public static final int WEP40 = 0; /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key */ public static final int WEP104 = 1; /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ public static final int TKIP = 2; /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ public static final int CCMP = 3; /** Hotspot 2.0 r2 OSEN * @hide */ public static final int GTK_NOT_USED = 4; public static final String varName = "group"; public static final String[] strings = { "WEP40", "WEP104", "TKIP", "CCMP", "GTK_NOT_USED" }; } /** Possible status of a network configuration. */ public static class Status { private Status() { } /** this is the network we are currently connected to */ public static final int CURRENT = 0; /** supplicant will not attempt to use this network */ public static final int DISABLED = 1; /** supplicant will consider this network available for association */ public static final int ENABLED = 2; public static final String[] strings = { "current", "disabled", "enabled" }; } /** @hide */ public static final int UNKNOWN_UID = -1; /** * The ID number that the supplicant uses to identify this * network configuration entry. This must be passed as an argument * to most calls into the supplicant. */ public int networkId; /** * The current status of this network configuration entry. * Fixme We need remove this field to use only Quality network selection status only * @see Status */ public int status; /** * The network's SSID. Can either be an ASCII string, * which must be enclosed in double quotation marks * (e.g., {@code "MyNetwork"}, or a string of * hex digits,which are not enclosed in quotes * (e.g., {@code 01a243f405}). */ public String SSID; /** * When set, this network configuration entry should only be used when * associating with the AP having the specified BSSID. The value is * a string in the format of an Ethernet MAC address, e.g., *
XX:XX:XX:XX:XX:XX
where each X
is a hex digit.
*/
public String BSSID;
/**
* 2GHz band.
* @hide
*/
public static final int AP_BAND_2GHZ = 0;
/**
* 5GHz band.
* @hide
*/
public static final int AP_BAND_5GHZ = 1;
/**
* The band which AP resides on
* 0-2G 1-5G
* By default, 2G is chosen
* @hide
*/
public int apBand = AP_BAND_2GHZ;
/**
* The channel which AP resides on,currently, US only
* 2G 1-11
* 5G 36,40,44,48,149,153,157,161,165
* 0 - find a random available channel according to the apBand
* @hide
*/
public int apChannel = 0;
/**
* Pre-shared key for use with WPA-PSK.
*
* When the value of this key is read, the actual key is
* not returned, just a "*" if the key has a value, or the null
* string otherwise.
*/
public String preSharedKey;
/**
* Up to four WEP keys. Either an ASCII string enclosed in double
* quotation marks (e.g., {@code "abcdef"} or a string
* of hex digits (e.g., {@code 0102030405}).
*
* When the value of one of these keys is read, the actual key is
* not returned, just a "*" if the key has a value, or the null
* string otherwise.
*/
public String[] wepKeys;
/** Default WEP key index, ranging from 0 to 3. */
public int wepTxKeyIndex;
/**
* Priority determines the preference given to a network by {@code wpa_supplicant}
* when choosing an access point with which to associate.
*/
public int priority;
/**
* This is a network that does not broadcast its SSID, so an
* SSID-specific probe request must be used for scans.
*/
public boolean hiddenSSID;
/**
* This is a network that requries Protected Management Frames (PMF).
* @hide
*/
public boolean requirePMF;
/**
* Update identifier, for Passpoint network.
* @hide
*/
public String updateIdentifier;
/**
* The set of key management protocols supported by this configuration.
* See {@link KeyMgmt} for descriptions of the values.
* Defaults to WPA-PSK WPA-EAP.
*/
public BitSet allowedKeyManagement;
/**
* The set of security protocols supported by this configuration.
* See {@link Protocol} for descriptions of the values.
* Defaults to WPA RSN.
*/
public BitSet allowedProtocols;
/**
* The set of authentication protocols supported by this configuration.
* See {@link AuthAlgorithm} for descriptions of the values.
* Defaults to automatic selection.
*/
public BitSet allowedAuthAlgorithms;
/**
* The set of pairwise ciphers for WPA supported by this configuration.
* See {@link PairwiseCipher} for descriptions of the values.
* Defaults to CCMP TKIP.
*/
public BitSet allowedPairwiseCiphers;
/**
* The set of group ciphers supported by this configuration.
* See {@link GroupCipher} for descriptions of the values.
* Defaults to CCMP TKIP WEP104 WEP40.
*/
public BitSet allowedGroupCiphers;
/**
* The enterprise configuration details specifying the EAP method,
* certificates and other settings associated with the EAP.
*/
public WifiEnterpriseConfig enterpriseConfig;
/**
* Fully qualified domain name of a passpoint configuration
*/
public String FQDN;
/**
* Name of passpoint credential provider
*/
public String providerFriendlyName;
/**
* Roaming Consortium Id list for passpoint credential; identifies a set of networks where
* passpoint credential will be considered valid
*/
public long[] roamingConsortiumIds;
/**
* @hide
* This network configuration is visible to and usable by other users on the
* same device.
*/
public boolean shared;
/**
* @hide
*/
private IpConfiguration mIpConfiguration;
/**
* @hide
* dhcp server MAC address if known
*/
public String dhcpServer;
/**
* @hide
* default Gateway MAC address if known
*/
public String defaultGwMacAddress;
/**
* @hide
* last failure
*/
public String lastFailure;
/**
* @hide
* last time we connected, this configuration had validated internet access
*/
public boolean validatedInternetAccess;
/**
* @hide
* The number of beacon intervals between Delivery Traffic Indication Maps (DTIM)
* This value is populated from scan results that contain Beacon Frames, which are infrequent.
* The value is not guaranteed to be set or current (Although it SHOULDNT change once set)
* Valid values are from 1 - 255. Initialized here as 0, use this to check if set.
*/
public int dtimInterval = 0;
/**
* @hide
* Uid of app creating the configuration
*/
@SystemApi
public int creatorUid;
/**
* @hide
* Uid of last app issuing a connection related command
*/
public int lastConnectUid;
/**
* @hide
* Uid of last app modifying the configuration
*/
@SystemApi
public int lastUpdateUid;
/**
* @hide
* Universal name for app creating the configuration
* see {#link {@link PackageManager#getNameForUid(int)}
*/
@SystemApi
public String creatorName;
/**
* @hide
* Universal name for app updating the configuration
* see {#link {@link PackageManager#getNameForUid(int)}
*/
@SystemApi
public String lastUpdateName;
/**
* @hide
* Status of user approval for connection
*/
public int userApproved = USER_UNSPECIFIED;
/** The Below RSSI thresholds are used to configure AutoJoin
* - GOOD/LOW/BAD thresholds are used so as to calculate link score
* - UNWANTED_SOFT are used by the blacklisting logic so as to handle
* the unwanted network message coming from CS
* - UNBLACKLIST thresholds are used so as to tweak the speed at which
* the network is unblacklisted (i.e. if
* it is seen with good RSSI, it is blacklisted faster)
* - INITIAL_AUTOJOIN_ATTEMPT, used to determine how close from
* the network we need to be before autojoin kicks in
*/
/** @hide **/
public static int INVALID_RSSI = -127;
/**
* @hide
* A summary of the RSSI and Band status for that configuration
* This is used as a temporary value by the auto-join controller
*/
public static final class Visibility {
public int rssi5; // strongest 5GHz RSSI
public int rssi24; // strongest 2.4GHz RSSI
public int num5; // number of BSSIDs on 5GHz
public int num24; // number of BSSIDs on 2.4GHz
public long age5; // timestamp of the strongest 5GHz BSSID (last time it was seen)
public long age24; // timestamp of the strongest 2.4GHz BSSID (last time it was seen)
public String BSSID24;
public String BSSID5;
public int score; // Debug only, indicate last score used for autojoin/cell-handover
public int currentNetworkBoost; // Debug only, indicate boost applied to RSSI if current
public int bandPreferenceBoost; // Debug only, indicate boost applied to RSSI if current
public int lastChoiceBoost; // Debug only, indicate last choice applied to this configuration
public String lastChoiceConfig; // Debug only, indicate last choice applied to this configuration
public Visibility() {
rssi5 = INVALID_RSSI;
rssi24 = INVALID_RSSI;
}
public Visibility(Visibility source) {
rssi5 = source.rssi5;
rssi24 = source.rssi24;
age24 = source.age24;
age5 = source.age5;
num24 = source.num24;
num5 = source.num5;
BSSID5 = source.BSSID5;
BSSID24 = source.BSSID24;
}
@Override
public String toString() {
StringBuilder sbuf = new StringBuilder();
sbuf.append("[");
if (rssi24 > INVALID_RSSI) {
sbuf.append(Integer.toString(rssi24));
sbuf.append(",");
sbuf.append(Integer.toString(num24));
if (BSSID24 != null) sbuf.append(",").append(BSSID24);
}
sbuf.append("; ");
if (rssi5 > INVALID_RSSI) {
sbuf.append(Integer.toString(rssi5));
sbuf.append(",");
sbuf.append(Integer.toString(num5));
if (BSSID5 != null) sbuf.append(",").append(BSSID5);
}
if (score != 0) {
sbuf.append("; ").append(score);
sbuf.append(", ").append(currentNetworkBoost);
sbuf.append(", ").append(bandPreferenceBoost);
if (lastChoiceConfig != null) {
sbuf.append(", ").append(lastChoiceBoost);
sbuf.append(", ").append(lastChoiceConfig);
}
}
sbuf.append("]");
return sbuf.toString();
}
}
/** @hide
* Cache the visibility status of this configuration.
* Visibility can change at any time depending on scan results availability.
* Owner of the WifiConfiguration is responsible to set this field based on
* recent scan results.
***/
public Visibility visibility;
/** @hide
* calculate and set Visibility for that configuration.
*
* age in milliseconds: we will consider only ScanResults that are more recent,
* i.e. younger.
***/
public void setVisibility(Visibility status) {
visibility = status;
}
// States for the userApproved field
/**
* @hide
* User hasn't specified if connection is okay
*/
public static final int USER_UNSPECIFIED = 0;
/**
* @hide
* User has approved this for connection
*/
public static final int USER_APPROVED = 1;
/**
* @hide
* User has banned this from connection
*/
public static final int USER_BANNED = 2;
/**
* @hide
* Waiting for user input
*/
public static final int USER_PENDING = 3;
/**
* @hide
* Number of reports indicating no Internet Access
*/
public int numNoInternetAccessReports;
/**
* @hide
* For debug: date at which the config was last updated
*/
public String updateTime;
/**
* @hide
* For debug: date at which the config was last updated
*/
public String creationTime;
/**
* @hide
* The WiFi configuration is considered to have no internet access for purpose of autojoining
* if there has been a report of it having no internet access, and, it never have had
* internet access in the past.
*/
public boolean hasNoInternetAccess() {
return numNoInternetAccessReports > 0 && !validatedInternetAccess;
}
/**
* The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a
* Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to
* this configuration and selects "don't ask again".
* @hide
*/
public boolean noInternetAccessExpected;
/**
* @hide
* Last time the system was connected to this configuration.
*/
public long lastConnected;
/**
* @hide
* Last time the system tried to connect and failed.
*/
public long lastConnectionFailure;
/**
* @hide
* Last time the system tried to roam and failed because of authentication failure or DHCP
* RENEW failure.
*/
public long lastRoamingFailure;
/** @hide */
public static int ROAMING_FAILURE_IP_CONFIG = 1;
/** @hide */
public static int ROAMING_FAILURE_AUTH_FAILURE = 2;
/**
* @hide
* Initial amount of time this Wifi configuration gets blacklisted for network switching
* because of roaming failure
*/
public long roamingFailureBlackListTimeMilli = 1000;
/**
* @hide
* Last roaming failure reason code
*/
public int lastRoamingFailureReason;
/**
* @hide
* Last time the system was disconnected to this configuration.
*/
public long lastDisconnected;
/**
* Set if the configuration was self added by the framework
* This boolean is cleared if we get a connect/save/ update or
* any wifiManager command that indicate the user interacted with the configuration
* since we will now consider that the configuration belong to him.
* @hide
*/
public boolean selfAdded;
/**
* Set if the configuration was self added by the framework
* This boolean is set once and never cleared. It is used
* so as we never loose track of who created the
* configuration in the first place.
* @hide
*/
public boolean didSelfAdd;
/**
* Peer WifiConfiguration this WifiConfiguration was added for
* @hide
*/
public String peerWifiConfiguration;
/**
* @hide
* Indicate that a WifiConfiguration is temporary and should not be saved
* nor considered by AutoJoin.
*/
public boolean ephemeral;
/**
* @hide
* A hint about whether or not the network represented by this WifiConfiguration
* is metered.
*/
public boolean meteredHint;
/**
* @hide
* Setting this value will force scan results associated with this configuration to
* be included in the bucket of networks that are externally scored.
* If not set, associated scan results will be treated as legacy saved networks and
* will take precedence over networks in the scored category.
*/
@SystemApi
public boolean useExternalScores;
/**
* @hide
* Number of time the scorer overrode a the priority based choice, when comparing two
* WifiConfigurations, note that since comparing WifiConfiguration happens very often
* potentially at every scan, this number might become very large, even on an idle
* system.
*/
@SystemApi
public int numScorerOverride;
/**
* @hide
* Number of time the scorer overrode a the priority based choice, and the comparison
* triggered a network switch
*/
@SystemApi
public int numScorerOverrideAndSwitchedNetwork;
/**
* @hide
* Number of time we associated to this configuration.
*/
@SystemApi
public int numAssociation;
/**
* @hide
* Number of time user disabled WiFi while associated to this configuration with Low RSSI.
*/
public int numUserTriggeredWifiDisableLowRSSI;
/**
* @hide
* Number of time user disabled WiFi while associated to this configuration with Bad RSSI.
*/
public int numUserTriggeredWifiDisableBadRSSI;
/**
* @hide
* Number of time user disabled WiFi while associated to this configuration
* and RSSI was not HIGH.
*/
public int numUserTriggeredWifiDisableNotHighRSSI;
/**
* @hide
* Number of ticks associated to this configuration with Low RSSI.
*/
public int numTicksAtLowRSSI;
/**
* @hide
* Number of ticks associated to this configuration with Bad RSSI.
*/
public int numTicksAtBadRSSI;
/**
* @hide
* Number of ticks associated to this configuration
* and RSSI was not HIGH.
*/
public int numTicksAtNotHighRSSI;
/**
* @hide
* Number of time user (WifiManager) triggered association to this configuration.
* TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps
*/
public int numUserTriggeredJoinAttempts;
/** @hide
* Boost given to RSSI on a home network for the purpose of calculating the score
* This adds stickiness to home networks, as defined by:
* - less than 4 known BSSIDs
* - PSK only
* - TODO: add a test to verify that all BSSIDs are behind same gateway
***/
public static final int HOME_NETWORK_RSSI_BOOST = 5;
/**
* @hide
* This class is used to contain all the information and API used for quality network selection
*/
public static class NetworkSelectionStatus {
/**
* Quality Network Selection Status enable, temporary disabled, permanently disabled
*/
/**
* This network is allowed to join Quality Network Selection
*/
public static final int NETWORK_SELECTION_ENABLED = 0;
/**
* network was temporary disabled. Can be re-enabled after a time period expire
*/
public static final int NETWORK_SELECTION_TEMPORARY_DISABLED = 1;
/**
* network was permanently disabled.
*/
public static final int NETWORK_SELECTION_PERMANENTLY_DISABLED = 2;
/**
* Maximum Network selection status
*/
public static final int NETWORK_SELECTION_STATUS_MAX = 3;
/**
* Quality network selection status String (for debug purpose). Use Quality network
* selection status value as index to extec the corresponding debug string
*/
private static final String[] QUALITY_NETWORK_SELECTION_STATUS = {
"NETWORK_SELECTION_ENABLED",
"NETWORK_SELECTION_TEMPORARY_DISABLED",
"NETWORK_SELECTION_PERMANENTLY_DISABLED"};
//Quality Network disabled reasons
/**
* Default value. Means not disabled
*/
public static final int NETWORK_SELECTION_ENABLE = 0;
/**
* @deprecated it is not used any more.
* This network is disabled because higher layer (>2) network is bad
*/
public static final int DISABLED_BAD_LINK = 1;
/**
* This network is disabled because multiple association rejects
*/
public static final int DISABLED_ASSOCIATION_REJECTION = 2;
/**
* This network is disabled because multiple authentication failure
*/
public static final int DISABLED_AUTHENTICATION_FAILURE = 3;
/**
* This network is disabled because multiple DHCP failure
*/
public static final int DISABLED_DHCP_FAILURE = 4;
/**
* This network is disabled because of security network but no credentials
*/
public static final int DISABLED_DNS_FAILURE = 5;
/**
* This network is disabled because EAP-TLS failure
*/
public static final int DISABLED_TLS_VERSION_MISMATCH = 6;
/**
* This network is disabled due to WifiManager disable it explicitly
*/
public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 7;
/**
* This network is disabled because no Internet connected and user do not want
*/
public static final int DISABLED_NO_INTERNET = 8;
/**
* This network is disabled due to WifiManager disable it explicitly
*/
public static final int DISABLED_BY_WIFI_MANAGER = 9;
/**
* This Maximum disable reason value
*/
public static final int NETWORK_SELECTION_DISABLED_MAX = 10;
/**
* Quality network selection disable reason String (for debug purpose)
*/
private static final String[] QUALITY_NETWORK_SELECTION_DISABLE_REASON = {
"NETWORK_SELECTION_ENABLE",
"NETWORK_SELECTION_DISABLED_BAD_LINK", // deprecated
"NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ",
"NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE",
"NETWORK_SELECTION_DISABLED_DHCP_FAILURE",
"NETWORK_SELECTION_DISABLED_DNS_FAILURE",
"NETWORK_SELECTION_DISABLED_TLS_VERSION",
"NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
"NETWORK_SELECTION_DISABLED_NO_INTERNET",
"NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER"};
/**
* Invalid time stamp for network selection disable
*/
public static final long INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP = -1L;
/**
* This constant indicates the current configuration has connect choice set
*/
private static final int CONNECT_CHOICE_EXISTS = 1;
/**
* This constant indicates the current configuration does not have connect choice set
*/
private static final int CONNECT_CHOICE_NOT_EXISTS = -1;
// fields for QualityNetwork Selection
/**
* Network selection status, should be in one of three status: enable, temporaily disabled
* or permanently disabled
*/
private int mStatus;
/**
* Reason for disable this network
*/
private int mNetworkSelectionDisableReason;
/**
* Last time we temporarily disabled the configuration
*/
private long mTemporarilyDisabledTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP;
/**
* counter for each Network selection disable reason
*/
private int[] mNetworkSeclectionDisableCounter = new int[NETWORK_SELECTION_DISABLED_MAX];
/**
* Connect Choice over this configuration
*
* When current wifi configuration is visible to the user but user explicitly choose to
* connect to another network X, the another networks X's configure key will be stored here.
* We will consider user has a preference of X over this network. And in the future,
* network selection will always give X a higher preference over this configuration.
* configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP
*/
private String mConnectChoice;
/**
* The system timestamp when we records the connectChoice. This value is obtained from
* System.currentTimeMillis
*/
private long mConnectChoiceTimestamp = INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP;
/**
* Used to cache the temporary candidate during the network selection procedure. It will be
* kept updating once a new scan result has a higher score than current one
*/
private ScanResult mCandidate;
/**
* Used to cache the score of the current temporary candidate during the network
* selection procedure.
*/
private int mCandidateScore;
/**
* Indicate whether this network is visible in latest Qualified Network Selection. This
* means there is scan result found related to this Configuration and meet the minimum
* requirement. The saved network need not join latest Qualified Network Selection. For
* example, it is disabled. True means network is visible in latest Qualified Network
* Selection and false means network is invisible
*/
private boolean mSeenInLastQualifiedNetworkSelection;
/**
* Boolean indicating if we have ever successfully connected to this network.
*
* This value will be set to true upon a successful connection.
* This value will be set to false if a previous value was not stored in the config or if
* the credentials are updated (ex. a password change).
*/
private boolean mHasEverConnected;
/**
* set whether this network is visible in latest Qualified Network Selection
* @param seen value set to candidate
*/
public void setSeenInLastQualifiedNetworkSelection(boolean seen) {
mSeenInLastQualifiedNetworkSelection = seen;
}
/**
* get whether this network is visible in latest Qualified Network Selection
* @return returns true -- network is visible in latest Qualified Network Selection
* false -- network is invisible in latest Qualified Network Selection
*/
public boolean getSeenInLastQualifiedNetworkSelection() {
return mSeenInLastQualifiedNetworkSelection;
}
/**
* set the temporary candidate of current network selection procedure
* @param scanCandidate {@link ScanResult} the candidate set to mCandidate
*/
public void setCandidate(ScanResult scanCandidate) {
mCandidate = scanCandidate;
}
/**
* get the temporary candidate of current network selection procedure
* @return returns {@link ScanResult} temporary candidate of current network selection
* procedure
*/
public ScanResult getCandidate() {
return mCandidate;
}
/**
* set the score of the temporary candidate of current network selection procedure
* @param score value set to mCandidateScore
*/
public void setCandidateScore(int score) {
mCandidateScore = score;
}
/**
* get the score of the temporary candidate of current network selection procedure
* @return returns score of the temporary candidate of current network selection procedure
*/
public int getCandidateScore() {
return mCandidateScore;
}
/**
* get user preferred choice over this configuration
*@return returns configKey of user preferred choice over this configuration
*/
public String getConnectChoice() {
return mConnectChoice;
}
/**
* set user preferred choice over this configuration
* @param newConnectChoice, the configKey of user preferred choice over this configuration
*/
public void setConnectChoice(String newConnectChoice) {
mConnectChoice = newConnectChoice;
}
/**
* get the timeStamp when user select a choice over this configuration
* @return returns when current connectChoice is set (time from System.currentTimeMillis)
*/
public long getConnectChoiceTimestamp() {
return mConnectChoiceTimestamp;
}
/**
* set the timeStamp when user select a choice over this configuration
* @param timeStamp, the timestamp set to connectChoiceTimestamp, expected timestamp should
* be obtained from System.currentTimeMillis
*/
public void setConnectChoiceTimestamp(long timeStamp) {
mConnectChoiceTimestamp = timeStamp;
}
/**
* get current Quality network selection status
* @return returns current Quality network selection status in String (for debug purpose)
*/
public String getNetworkStatusString() {
return QUALITY_NETWORK_SELECTION_STATUS[mStatus];
}
public void setHasEverConnected(boolean value) {
mHasEverConnected = value;
}
public boolean getHasEverConnected() {
return mHasEverConnected;
}
private NetworkSelectionStatus() {
// previously stored configs will not have this parameter, so we default to false.
mHasEverConnected = false;
};
/**
* @param reason specific error reason
* @return corresponding network disable reason String (for debug purpose)
*/
public static String getNetworkDisableReasonString(int reason) {
if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
return QUALITY_NETWORK_SELECTION_DISABLE_REASON[reason];
} else {
return null;
}
}
/**
* get current network disable reason
* @return current network disable reason in String (for debug purpose)
*/
public String getNetworkDisableReasonString() {
return QUALITY_NETWORK_SELECTION_DISABLE_REASON[mNetworkSelectionDisableReason];
}
/**
* get current network network selection status
* @return return current network network selection status
*/
public int getNetworkSelectionStatus() {
return mStatus;
}
/**
* @return whether current network is enabled to join network selection
*/
public boolean isNetworkEnabled() {
return mStatus == NETWORK_SELECTION_ENABLED;
}
/**
* @return whether current network is temporary disabled
*/
public boolean isNetworkTemporaryDisabled() {
return mStatus == NETWORK_SELECTION_TEMPORARY_DISABLED;
}
/**
* @return returns whether current network is permanently disabled
*/
public boolean isNetworkPermanentlyDisabled() {
return mStatus == NETWORK_SELECTION_PERMANENTLY_DISABLED;
}
/**
* set current networ work selection status
* @param status network selection status to set
*/
public void setNetworkSelectionStatus(int status) {
if (status >= 0 && status < NETWORK_SELECTION_STATUS_MAX) {
mStatus = status;
}
}
/**
* @return returns current network's disable reason
*/
public int getNetworkSelectionDisableReason() {
return mNetworkSelectionDisableReason;
}
/**
* set Network disable reason
* @param reason Network disable reason
*/
public void setNetworkSelectionDisableReason(int reason) {
if (reason >= 0 && reason < NETWORK_SELECTION_DISABLED_MAX) {
mNetworkSelectionDisableReason = reason;
} else {
throw new IllegalArgumentException("Illegal reason value: " + reason);
}
}
/**
* check whether network is disabled by this reason
* @param reason a specific disable reason
* @return true -- network is disabled for this reason
* false -- network is not disabled for this reason
*/
public boolean isDisabledByReason(int reason) {
return mNetworkSelectionDisableReason == reason;
}
/**
* @param timeStamp Set when current network is disabled in millisecond since January 1,
* 1970 00:00:00.0 UTC
*/
public void setDisableTime(long timeStamp) {
mTemporarilyDisabledTimestamp = timeStamp;
}
/**
* @return returns when current network is disabled in millisecond since January 1,
* 1970 00:00:00.0 UTC
*/
public long getDisableTime() {
return mTemporarilyDisabledTimestamp;
}
/**
* get the disable counter of a specific reason
* @param reason specific failure reason
* @exception throw IllegalArgumentException for illegal input
* @return counter number for specific error reason.
*/
public int getDisableReasonCounter(int reason) {
if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
return mNetworkSeclectionDisableCounter[reason];
} else {
throw new IllegalArgumentException("Illegal reason value: " + reason);
}
}
/**
* set the counter of a specific failure reason
* @param reason reason for disable error
* @param value the counter value for this specific reason
* @exception throw IllegalArgumentException for illegal input
*/
public void setDisableReasonCounter(int reason, int value) {
if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
mNetworkSeclectionDisableCounter[reason] = value;
} else {
throw new IllegalArgumentException("Illegal reason value: " + reason);
}
}
/**
* increment the counter of a specific failure reason
* @param reason a specific failure reason
* @exception throw IllegalArgumentException for illegal input
*/
public void incrementDisableReasonCounter(int reason) {
if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
mNetworkSeclectionDisableCounter[reason]++;
} else {
throw new IllegalArgumentException("Illegal reason value: " + reason);
}
}
/**
* clear the counter of a specific failure reason
* @hide
* @param reason a specific failure reason
* @exception throw IllegalArgumentException for illegal input
*/
public void clearDisableReasonCounter(int reason) {
if (reason >= NETWORK_SELECTION_ENABLE && reason < NETWORK_SELECTION_DISABLED_MAX) {
mNetworkSeclectionDisableCounter[reason] = NETWORK_SELECTION_ENABLE;
} else {
throw new IllegalArgumentException("Illegal reason value: " + reason);
}
}
/**
* clear all the failure reason counters
*/
public void clearDisableReasonCounter() {
Arrays.fill(mNetworkSeclectionDisableCounter, NETWORK_SELECTION_ENABLE);
}
/**
* BSSID for connection to this network (through network selection procedure)
*/
private String mNetworkSelectionBSSID;
/**
* get current network Selection BSSID
* @return current network Selection BSSID
*/
public String getNetworkSelectionBSSID() {
return mNetworkSelectionBSSID;
}
/**
* set network Selection BSSID
* @param bssid The target BSSID for assocaition
*/
public void setNetworkSelectionBSSID(String bssid) {
mNetworkSelectionBSSID = bssid;
}
public void copy(NetworkSelectionStatus source) {
mStatus = source.mStatus;
mNetworkSelectionDisableReason = source.mNetworkSelectionDisableReason;
for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX;
index++) {
mNetworkSeclectionDisableCounter[index] =
source.mNetworkSeclectionDisableCounter[index];
}
mTemporarilyDisabledTimestamp = source.mTemporarilyDisabledTimestamp;
mNetworkSelectionBSSID = source.mNetworkSelectionBSSID;
setConnectChoice(source.getConnectChoice());
setConnectChoiceTimestamp(source.getConnectChoiceTimestamp());
setHasEverConnected(source.getHasEverConnected());
}
public void writeToParcel(Parcel dest) {
dest.writeInt(getNetworkSelectionStatus());
dest.writeInt(getNetworkSelectionDisableReason());
for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX;
index++) {
dest.writeInt(getDisableReasonCounter(index));
}
dest.writeLong(getDisableTime());
dest.writeString(getNetworkSelectionBSSID());
if (getConnectChoice() != null) {
dest.writeInt(CONNECT_CHOICE_EXISTS);
dest.writeString(getConnectChoice());
dest.writeLong(getConnectChoiceTimestamp());
} else {
dest.writeInt(CONNECT_CHOICE_NOT_EXISTS);
}
dest.writeInt(getHasEverConnected() ? 1 : 0);
}
public void readFromParcel(Parcel in) {
setNetworkSelectionStatus(in.readInt());
setNetworkSelectionDisableReason(in.readInt());
for (int index = NETWORK_SELECTION_ENABLE; index < NETWORK_SELECTION_DISABLED_MAX;
index++) {
setDisableReasonCounter(index, in.readInt());
}
setDisableTime(in.readLong());
setNetworkSelectionBSSID(in.readString());
if (in.readInt() == CONNECT_CHOICE_EXISTS) {
setConnectChoice(in.readString());
setConnectChoiceTimestamp(in.readLong());
} else {
setConnectChoice(null);
setConnectChoiceTimestamp(INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
}
setHasEverConnected(in.readInt() != 0);
}
}
/**
* @hide
* network selection related member
*/
private final NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus();
/**
* @hide
* @return network selection status
*/
public NetworkSelectionStatus getNetworkSelectionStatus() {
return mNetworkSelectionStatus;
}
/**
* @hide
* Linked Configurations: represent the set of Wificonfigurations that are equivalent
* regarding roaming and auto-joining.
* The linked configuration may or may not have same SSID, and may or may not have same
* credentials.
* For instance, linked configurations will have same defaultGwMacAddress or same dhcp server.
*/
public HashMap