1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.wifi; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.SystemApi; 22 import android.net.wifi.ScanResult.WifiBand; 23 import android.os.Build; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 import android.util.SparseArray; 27 28 import androidx.annotation.RequiresApi; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.Arrays; 33 import java.util.Objects; 34 import java.util.function.Consumer; 35 36 /** 37 * An Object used in {@link WifiManager#setNetworkSelectionConfig(WifiNetworkSelectionConfig)}. 38 * @hide 39 */ 40 @SystemApi 41 @RequiresApi(Build.VERSION_CODES.TIRAMISU) 42 public final class WifiNetworkSelectionConfig implements Parcelable { 43 /** @hide */ 44 @Retention(RetentionPolicy.SOURCE) 45 @IntDef(prefix = {"ASSOCIATED_NETWORK_SELECTION_OVERRIDE_"}, value = { 46 ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE, 47 ASSOCIATED_NETWORK_SELECTION_OVERRIDE_ENABLED, 48 ASSOCIATED_NETWORK_SELECTION_OVERRIDE_DISABLED}) 49 public @interface AssociatedNetworkSelectionOverride {} 50 /** 51 * A constant used in {@link Builder#setAssociatedNetworkSelectionOverride(int)} 52 * This is the default value which performs no override. 53 */ 54 public static final int ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE = 0; 55 /** 56 * A constant used in {{@link Builder#setAssociatedNetworkSelectionOverride(int)} 57 * Overrides the config_wifi_framework_enable_associated_network_selection overlay to true to 58 * allow the wifi framework to automatically select and switch to a better wifi network while 59 * already connected. 60 */ 61 public static final int ASSOCIATED_NETWORK_SELECTION_OVERRIDE_ENABLED = 1; 62 /** 63 * A constant used in {@link Builder#setAssociatedNetworkSelectionOverride(int)} 64 * Overrides the config_wifi_framework_enable_associated_network_selection overlay to false to 65 * disallow the wifi framework to automatically select and connect to another network while 66 * already connected. 67 */ 68 public static final int ASSOCIATED_NETWORK_SELECTION_OVERRIDE_DISABLED = 2; 69 70 /** @hide */ 71 @Retention(RetentionPolicy.SOURCE) 72 @IntDef(prefix = {"FREQUENCY_WEIGHT_"}, value = { 73 FREQUENCY_WEIGHT_LOW, 74 FREQUENCY_WEIGHT_HIGH}) 75 public @interface FrequencyWeight {} 76 77 /** 78 * A constant used in {@link Builder#setFrequencyWeights(SparseArray)} to indicate a low 79 * preference for the frequency it's associated with. 80 */ 81 public static final int FREQUENCY_WEIGHT_LOW = 0; 82 /** 83 * A constant used in {@link Builder#setFrequencyWeights(SparseArray)} to indicate a high 84 * preference for the frequency it's associated with. 85 */ 86 public static final int FREQUENCY_WEIGHT_HIGH = 1; 87 88 private boolean mSufficiencyCheckEnabledWhenScreenOff = true; 89 private boolean mSufficiencyCheckEnabledWhenScreenOn = true; 90 private boolean mUserConnectChoiceOverrideEnabled = true; 91 private boolean mLastSelectionWeightEnabled = true; 92 private int mAssociatedNetworkSelectionOverride = ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE; 93 94 /** RSSI thresholds for 2.4 GHz band (dBm) */ 95 private int[] mRssi2Thresholds = new int[4]; 96 97 /** RSSI thresholds for 5 GHz band (dBm) */ 98 private int[] mRssi5Thresholds = new int[4]; 99 100 /** RSSI thresholds for 6 GHz band (dBm) */ 101 private int[] mRssi6Thresholds = new int[4]; 102 103 /** Frequency weight list */ 104 private SparseArray<Integer> mFrequencyWeights = new SparseArray<>(); 105 106 // empty constructor WifiNetworkSelectionConfig()107 private WifiNetworkSelectionConfig() { 108 109 } 110 111 // copy constructor used by Builder WifiNetworkSelectionConfig(WifiNetworkSelectionConfig that)112 private WifiNetworkSelectionConfig(WifiNetworkSelectionConfig that) { 113 mSufficiencyCheckEnabledWhenScreenOff = that.mSufficiencyCheckEnabledWhenScreenOff; 114 mSufficiencyCheckEnabledWhenScreenOn = that.mSufficiencyCheckEnabledWhenScreenOn; 115 mAssociatedNetworkSelectionOverride = that.mAssociatedNetworkSelectionOverride; 116 mUserConnectChoiceOverrideEnabled = that.mUserConnectChoiceOverrideEnabled; 117 mLastSelectionWeightEnabled = that.mLastSelectionWeightEnabled; 118 mRssi2Thresholds = that.mRssi2Thresholds; 119 mRssi5Thresholds = that.mRssi5Thresholds; 120 mRssi6Thresholds = that.mRssi6Thresholds; 121 mFrequencyWeights = that.mFrequencyWeights; 122 } 123 124 /** 125 * See {@link Builder#setSufficiencyCheckEnabledWhenScreenOff(boolean)}. 126 */ isSufficiencyCheckEnabledWhenScreenOff()127 public boolean isSufficiencyCheckEnabledWhenScreenOff() { 128 return mSufficiencyCheckEnabledWhenScreenOff; 129 } 130 131 /** 132 * See {@link Builder#setSufficiencyCheckEnabledWhenScreenOn(boolean)}. 133 */ isSufficiencyCheckEnabledWhenScreenOn()134 public boolean isSufficiencyCheckEnabledWhenScreenOn() { 135 return mSufficiencyCheckEnabledWhenScreenOn; 136 } 137 138 /** 139 * See {@link Builder#setUserConnectChoiceOverrideEnabled(boolean)}. 140 */ isUserConnectChoiceOverrideEnabled()141 public boolean isUserConnectChoiceOverrideEnabled() { 142 return mUserConnectChoiceOverrideEnabled; 143 } 144 145 /** 146 * See {@link Builder#setLastSelectionWeightEnabled(boolean)}. 147 */ isLastSelectionWeightEnabled()148 public boolean isLastSelectionWeightEnabled() { 149 return mLastSelectionWeightEnabled; 150 } 151 152 /** 153 * See {@link Builder#setAssociatedNetworkSelectionOverride(int)}. 154 */ getAssociatedNetworkSelectionOverride()155 public @AssociatedNetworkSelectionOverride int getAssociatedNetworkSelectionOverride() { 156 return mAssociatedNetworkSelectionOverride; 157 } 158 isValidAssociatedNetworkSelectionOverride(int override)159 private static boolean isValidAssociatedNetworkSelectionOverride(int override) { 160 return override >= ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE 161 && override <= ASSOCIATED_NETWORK_SELECTION_OVERRIDE_DISABLED; 162 } 163 isValidBand(@ifiBand int band)164 private static boolean isValidBand(@WifiBand int band) { 165 switch (band) { 166 case ScanResult.WIFI_BAND_24_GHZ: 167 case ScanResult.WIFI_BAND_5_GHZ: 168 case ScanResult.WIFI_BAND_6_GHZ: 169 return true; 170 default: 171 return false; 172 } 173 } 174 isValidRssiThresholdArray(int[] thresholds)175 private static boolean isValidRssiThresholdArray(int[] thresholds) { 176 if (thresholds == null || thresholds.length != 4) return false; 177 178 if (!isRssiThresholdResetArray(thresholds)) { 179 int low = WifiInfo.MIN_RSSI - 1; 180 int high = Math.min(WifiInfo.MAX_RSSI, -1); 181 for (int i = 0; i < thresholds.length; i++) { 182 if (thresholds[i] <= low || thresholds[i] > high) { 183 return false; 184 } 185 low = thresholds[i]; 186 } 187 } 188 return true; 189 } 190 isValidFrequencyWeightArray(SparseArray<Integer> weights)191 private static boolean isValidFrequencyWeightArray(SparseArray<Integer> weights) { 192 if (weights == null) return false; 193 194 for (int i = 0; i < weights.size(); i++) { 195 int value = weights.valueAt(i); 196 if (value < FREQUENCY_WEIGHT_LOW || value > FREQUENCY_WEIGHT_HIGH) return false; 197 } 198 return true; 199 } 200 201 /** 202 * Check whether the given RSSI threshold array contains all 0s. 203 * @hide 204 */ isRssiThresholdResetArray(@onNull int[] thresholds)205 public static boolean isRssiThresholdResetArray(@NonNull int[] thresholds) { 206 for (int value : thresholds) { 207 if (value != 0) return false; 208 } 209 return true; 210 } 211 212 /** 213 * Check whether the current configuration is valid. 214 * @hide 215 */ isValid()216 public boolean isValid() { 217 return isValidAssociatedNetworkSelectionOverride(mAssociatedNetworkSelectionOverride) 218 && isValidRssiThresholdArray(mRssi2Thresholds) 219 && isValidRssiThresholdArray(mRssi5Thresholds) 220 && isValidRssiThresholdArray(mRssi6Thresholds) 221 && isValidFrequencyWeightArray(mFrequencyWeights); 222 } 223 224 /** 225 * See {@link Builder#setRssiThresholds(int, int[])}. 226 * Returns RSSI thresholds for the input band. 227 * 228 * @throws IllegalArgumentException if the input band is not a supported {@link WifiBand} 229 */ getRssiThresholds(@ifiBand int band)230 public @NonNull int[] getRssiThresholds(@WifiBand int band) { 231 if (!isValidBand(band)) { 232 throw new IllegalArgumentException("Invalid band=" + band); 233 } 234 switch (band) { 235 case ScanResult.WIFI_BAND_24_GHZ: 236 return mRssi2Thresholds; 237 case ScanResult.WIFI_BAND_5_GHZ: 238 return mRssi5Thresholds; 239 case ScanResult.WIFI_BAND_6_GHZ: 240 return mRssi6Thresholds; 241 } 242 throw new IllegalArgumentException("Did not find RSSI thresholds for band=" + band); 243 } 244 245 /** 246 * See {@link Builder#setFrequencyWeights(SparseArray)}. 247 */ getFrequencyWeights()248 public @NonNull SparseArray<Integer> getFrequencyWeights() { 249 return mFrequencyWeights; 250 } 251 252 /** 253 * Used to create a {@link WifiNetworkSelectionConfig} Object. 254 */ 255 public static final class Builder { 256 WifiNetworkSelectionConfig mWifiNetworkSelectionConfig = new WifiNetworkSelectionConfig(); 257 Builder()258 public Builder() { 259 mWifiNetworkSelectionConfig.mSufficiencyCheckEnabledWhenScreenOff = true; 260 mWifiNetworkSelectionConfig.mSufficiencyCheckEnabledWhenScreenOn = true; 261 mWifiNetworkSelectionConfig.mUserConnectChoiceOverrideEnabled = true; 262 mWifiNetworkSelectionConfig.mLastSelectionWeightEnabled = true; 263 mWifiNetworkSelectionConfig.mAssociatedNetworkSelectionOverride = 264 ASSOCIATED_NETWORK_SELECTION_OVERRIDE_NONE; 265 mWifiNetworkSelectionConfig.mRssi2Thresholds = new int[4]; 266 mWifiNetworkSelectionConfig.mRssi5Thresholds = new int[4]; 267 mWifiNetworkSelectionConfig.mRssi6Thresholds = new int[4]; 268 mWifiNetworkSelectionConfig.mFrequencyWeights = new SparseArray<>(); 269 } 270 Builder(@onNull WifiNetworkSelectionConfig config)271 public Builder(@NonNull WifiNetworkSelectionConfig config) { 272 mWifiNetworkSelectionConfig = config; 273 } 274 275 /** 276 * This setting affects wifi network selection behavior while already connected to a 277 * network, and is only relevant if associated network selection 278 * (see {@link #setAssociatedNetworkSelectionOverride(int)}) is enabled. Enable or disable 279 * network sufficiency check when wifi is connected and the screen is off. 280 * <p> 281 * If the sufficiency check is enabled, multiple parameters such as the RSSI and estimated 282 * throughput will be used to determine if the current network is sufficient. When the 283 * current network is found sufficient, the wifi framework will not attempt a network switch 284 * even if a potentially better network is available. When the current network is found 285 * insufficient, the wifi framework will keep trying to score other networks against the 286 * current network attempting to find and connect to a better alternative. 287 * <p> 288 * If the sufficiency check is disabled, then the currently connected network will always 289 * be considered insufficient. See the previous paragraph on the wifi framework's behavior 290 * when the current network is insufficient. 291 * <p> 292 * By default, network sufficiency check is enabled for both screen on and screen off cases. 293 * @param enabled Set to true to enable sufficiency check, and false to disable sufficiency 294 * check. 295 */ setSufficiencyCheckEnabledWhenScreenOff(boolean enabled)296 public @NonNull Builder setSufficiencyCheckEnabledWhenScreenOff(boolean enabled) { 297 mWifiNetworkSelectionConfig.mSufficiencyCheckEnabledWhenScreenOff = enabled; 298 return this; 299 } 300 301 /** 302 * This setting affects wifi network selection behavior while already connected to a 303 * network, and is only relevant if associated network selection 304 * (see {@link #setAssociatedNetworkSelectionOverride(int)}) is enabled. Enable or disable 305 * network sufficiency check when wifi is connected and the screen is on. 306 * <p> 307 * If the sufficiency check is enabled, multiple parameters such as the RSSI and estimated 308 * throughput will be used to determine if the current network is sufficient. When the 309 * current network is found sufficient, the wifi framework will not attempt a network switch 310 * even if a potentially better network is available. When the current network is found 311 * insufficient, the wifi framework will keep trying to score other networks against the 312 * current network attempting to find and connect to a better alternative. 313 * <p> 314 * If the sufficiency check is disabled, then the currently connected network will always 315 * be considered insufficient. See the previous paragraph on the wifi framework's behavior 316 * when the current network is insufficient. 317 * <p> 318 * By default, network sufficiency check is enabled for both screen on and screen off cases. 319 * @param enabled Set to true to enable sufficiency check, and false to disable sufficiency 320 * check. 321 */ setSufficiencyCheckEnabledWhenScreenOn(boolean enabled)322 public @NonNull Builder setSufficiencyCheckEnabledWhenScreenOn(boolean enabled) { 323 mWifiNetworkSelectionConfig.mSufficiencyCheckEnabledWhenScreenOn = enabled; 324 return this; 325 } 326 327 /** 328 * Override the value programmed by the 329 * {@code config_wifi_framework_enable_associated_network_selection} overlay with one of the 330 * {@code ASSOCIATED_NETWORK_SELECTION_OVERRIDE_} values. When the overlay is enabled, 331 * the wifi framework is allowed to automatically select and switch to a better wifi 332 * network while already connected. When the overlay is disabled, the wifi framework will 333 * simply stay connected to the connected network and will not attempt to automatically 334 * switch to another network. 335 * <p> 336 * By default, there is no override, and the framework will use the value set in the 337 * overlay. 338 * @param override the value to override the overlay as. 339 * @throws IllegalArgumentException if the input is invalid. 340 */ setAssociatedNetworkSelectionOverride( @ssociatedNetworkSelectionOverride int override)341 public @NonNull Builder setAssociatedNetworkSelectionOverride( 342 @AssociatedNetworkSelectionOverride int override) throws IllegalArgumentException { 343 if (!isValidAssociatedNetworkSelectionOverride(override)) { 344 throw new IllegalArgumentException("Invalid override=" + override); 345 } 346 mWifiNetworkSelectionConfig.mAssociatedNetworkSelectionOverride = override; 347 return this; 348 } 349 350 /** 351 * Enable or disable candidate override with the user connect choice. 352 * <p> 353 * If the override is enabled, the network selector overrides any selected candidate 354 * with a network previously chosen by the user over the candidate (i.e. when the 355 * candidate was connected the user explicitly selected another network), if one exists. 356 * <p> 357 * If the override is disabled, network selector uses the network nominator candidate 358 * and does not override it with the user chosen configuration. 359 * <p> 360 * By default, user connect choice override is enabled. 361 * @param enabled Set to true to enable candidate override with the user connect choice, 362 * and false to disable the override. 363 */ setUserConnectChoiceOverrideEnabled(boolean enabled)364 public @NonNull Builder setUserConnectChoiceOverrideEnabled(boolean enabled) { 365 mWifiNetworkSelectionConfig.mUserConnectChoiceOverrideEnabled = enabled; 366 return this; 367 } 368 369 /** 370 * Enable or disable last selection weight. 371 * <p> 372 * If the last selection weight is enabled, network selector prefers the latest 373 * user selected network over all other networks for a limited duration. 374 * This duration is configurable via {@code config_wifiFrameworkLastSelectionMinutes}. 375 * <p> 376 * If the last selection weight is disabled, network selector does not prefer a 377 * recently selected network over other networks. 378 * <p> 379 * By default, last selection weight is enabled. 380 * @param enabled Set to true to enable the last selection weight, 381 * and false to disable it. 382 */ setLastSelectionWeightEnabled(boolean enabled)383 public @NonNull Builder setLastSelectionWeightEnabled(boolean enabled) { 384 mWifiNetworkSelectionConfig.mLastSelectionWeightEnabled = enabled; 385 return this; 386 } 387 388 /** 389 * Sets the RSSI thresholds for the input band. 390 * <p> 391 * If the RSSI thresholds are set, network selector uses these values over the 392 * following overlay configured values for the specified input band. 393 * For {@code ScanResult.WIFI_BAND_24_GHZ}: 394 * <ul> 395 * <li>{@code config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz}</li> 396 * <li>{@code config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz}</li> 397 * <li>{@code config_wifi_framework_wifi_score_low_rssi_threshold_24GHz}</li> 398 * <li>{@code config_wifi_framework_wifi_score_good_rssi_threshold_24GHz}</li> 399 * </ul> 400 * For {@code ScanResult.WIFI_BAND_5_GHZ}: 401 * <ul> 402 * <li>{@code config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz}</li> 403 * <li>{@code config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz}</li> 404 * <li>{@code config_wifi_framework_wifi_score_low_rssi_threshold_5GHz}</li> 405 * <li>{@code config_wifi_framework_wifi_score_good_rssi_threshold_5GHz}</li> 406 * </ul> 407 * For {@code ScanResult.WIFI_BAND_6_GHZ}: 408 * <ul> 409 * <li>{@code config_wifiFrameworkScoreBadRssiThreshold6ghz}</li> 410 * <li>{@code config_wifiFrameworkScoreEntryRssiThreshold6ghz}</li> 411 * <li>{@code config_wifiFrameworkScoreLowRssiThreshold6ghz}</li> 412 * <li>{@code config_wifiFrameworkScoreGoodRssiThreshold6ghz}</li> 413 * </ul> 414 * <p> 415 * The input thresholds override the overlays listed above in the respective order 416 * so it must be an int array with 4 values. 417 * The values must be between -126 and -1 and the array must be strictly increasing. 418 * For example, [-80, -70, -60, -50] is a valid input while [-70, -70, -60, -50] is not 419 * since the array is not strictly increasing. 420 * The only exception to these rules is [0, 0, 0, 0], which is used to remove any 421 * RSSI thresholds set. 422 * <p> 423 * The input band must be one of the following {@link WifiBand}: 424 * <ul> 425 * <li>{@code ScanResult.WIFI_BAND_24_GHZ}</li> 426 * <li>{@code ScanResult.WIFI_BAND_5_GHZ}</li> 427 * <li>{@code ScanResult.WIFI_BAND_6_GHZ}</li> 428 * </ul> 429 * <p> 430 * To remove the RSSI thresholds set, pass in an array with 0s as the thresholds. 431 * The network selector will go back to using the overlay configured values. 432 * @param band {@link WifiBand} you want to set the RSSI thresholds for 433 * @param thresholds RSSI thresholds 434 * @throws IllegalArgumentException if the input is invalid. 435 */ setRssiThresholds(@ifiBand int band, @NonNull int[] thresholds)436 public @NonNull Builder setRssiThresholds(@WifiBand int band, @NonNull int[] thresholds) 437 throws IllegalArgumentException { 438 if (!isValidRssiThresholdArray(thresholds)) { 439 throw new IllegalArgumentException("Invalid RSSI thresholds=" 440 + Arrays.toString(thresholds)); 441 } 442 if (!isValidBand(band)) { 443 throw new IllegalArgumentException("Invalid band=" + band); 444 } 445 switch (band) { 446 case ScanResult.WIFI_BAND_24_GHZ: 447 mWifiNetworkSelectionConfig.mRssi2Thresholds = thresholds; 448 break; 449 case ScanResult.WIFI_BAND_5_GHZ: 450 mWifiNetworkSelectionConfig.mRssi5Thresholds = thresholds; 451 break; 452 case ScanResult.WIFI_BAND_6_GHZ: 453 mWifiNetworkSelectionConfig.mRssi6Thresholds = thresholds; 454 break; 455 } 456 return this; 457 } 458 459 /** 460 * Sets the frequency weights that will be used by the network selector to provide 461 * a bonus or penalty to the specified frequencies in the list. 462 * <p> 463 * The input SparseArray has to adhere to the following (key, value) format. 464 * Key: frequency the weight needs to be applied to in MHz (ex. 5201MHz -> 5201) 465 * Value: one of {@link FrequencyWeight} 466 * <ul> 467 * <li>{@link #FREQUENCY_WEIGHT_LOW}</li> 468 * <li>{@link #FREQUENCY_WEIGHT_HIGH}</li> 469 * </ul> 470 * <p> 471 * By default, all frequencies not present in the list will not have any frequency weight. 472 * <p> 473 * To removed the frequency weights set, pass in an empty SparseArray. 474 * The network selector will go back to treating all the frequencies with 475 * an equal preference. 476 * @param weights frequency weights 477 * @throws IllegalArgumentException if the input is invalid. 478 */ setFrequencyWeights(@onNull SparseArray<Integer> weights)479 public @NonNull Builder setFrequencyWeights(@NonNull SparseArray<Integer> weights) 480 throws IllegalArgumentException { 481 if (!isValidFrequencyWeightArray(weights)) { 482 if (weights == null) { 483 throw new IllegalArgumentException("Invalid frequency weights=null"); 484 } 485 throw new IllegalArgumentException("Invalid frequency weights=" 486 + weights.toString()); 487 } 488 mWifiNetworkSelectionConfig.mFrequencyWeights = weights; 489 return this; 490 } 491 492 /** 493 * Creates a WifiNetworkSelectionConfig for use in 494 * {@link WifiManager#setNetworkSelectionConfig(WifiNetworkSelectionConfig, Consumer)} 495 */ build()496 public @NonNull WifiNetworkSelectionConfig build() { 497 return new WifiNetworkSelectionConfig(mWifiNetworkSelectionConfig); 498 } 499 } 500 501 @Override hashCode()502 public int hashCode() { 503 return Objects.hash(mSufficiencyCheckEnabledWhenScreenOff, 504 mSufficiencyCheckEnabledWhenScreenOn, mAssociatedNetworkSelectionOverride, 505 mUserConnectChoiceOverrideEnabled, mLastSelectionWeightEnabled, 506 Arrays.hashCode(mRssi2Thresholds), Arrays.hashCode(mRssi5Thresholds), 507 Arrays.hashCode(mRssi6Thresholds), mFrequencyWeights.contentHashCode()); 508 } 509 510 @Override equals(Object obj)511 public boolean equals(Object obj) { 512 if (this == obj) { 513 return true; 514 } 515 if (!(obj instanceof WifiNetworkSelectionConfig)) { 516 return false; 517 } 518 WifiNetworkSelectionConfig lhs = (WifiNetworkSelectionConfig) obj; 519 return mSufficiencyCheckEnabledWhenScreenOff == lhs.mSufficiencyCheckEnabledWhenScreenOff 520 && mSufficiencyCheckEnabledWhenScreenOn == lhs.mSufficiencyCheckEnabledWhenScreenOn 521 && mAssociatedNetworkSelectionOverride == lhs.mAssociatedNetworkSelectionOverride 522 && mUserConnectChoiceOverrideEnabled == lhs.mUserConnectChoiceOverrideEnabled 523 && mLastSelectionWeightEnabled == lhs.mLastSelectionWeightEnabled 524 && Arrays.equals(mRssi2Thresholds, lhs.mRssi2Thresholds) 525 && Arrays.equals(mRssi5Thresholds, lhs.mRssi5Thresholds) 526 && Arrays.equals(mRssi6Thresholds, lhs.mRssi6Thresholds) 527 && mFrequencyWeights.contentEquals(lhs.mFrequencyWeights); 528 } 529 530 public static final @NonNull Creator<WifiNetworkSelectionConfig> CREATOR = 531 new Creator<WifiNetworkSelectionConfig>() { 532 @Override 533 public WifiNetworkSelectionConfig createFromParcel(Parcel in) { 534 WifiNetworkSelectionConfig config = new WifiNetworkSelectionConfig(); 535 config.mSufficiencyCheckEnabledWhenScreenOff = in.readBoolean(); 536 config.mSufficiencyCheckEnabledWhenScreenOn = in.readBoolean(); 537 config.mAssociatedNetworkSelectionOverride = in.readInt(); 538 config.mUserConnectChoiceOverrideEnabled = in.readBoolean(); 539 config.mLastSelectionWeightEnabled = in.readBoolean(); 540 in.readIntArray(config.mRssi2Thresholds); 541 in.readIntArray(config.mRssi5Thresholds); 542 in.readIntArray(config.mRssi6Thresholds); 543 config.mFrequencyWeights = in.readSparseArray(null, java.lang.Integer.class); 544 return config; 545 } 546 547 @Override 548 public WifiNetworkSelectionConfig[] newArray(int size) { 549 return new WifiNetworkSelectionConfig[size]; 550 } 551 }; 552 553 @Override describeContents()554 public int describeContents() { 555 return 0; 556 } 557 558 @Override writeToParcel(@onNull Parcel dest, int flags)559 public void writeToParcel(@NonNull Parcel dest, int flags) { 560 dest.writeBoolean(mSufficiencyCheckEnabledWhenScreenOff); 561 dest.writeBoolean(mSufficiencyCheckEnabledWhenScreenOn); 562 dest.writeInt(mAssociatedNetworkSelectionOverride); 563 dest.writeBoolean(mUserConnectChoiceOverrideEnabled); 564 dest.writeBoolean(mLastSelectionWeightEnabled); 565 dest.writeIntArray(mRssi2Thresholds); 566 dest.writeIntArray(mRssi5Thresholds); 567 dest.writeIntArray(mRssi6Thresholds); 568 dest.writeSparseArray(mFrequencyWeights); 569 } 570 571 @Override toString()572 public String toString() { 573 StringBuilder sb = new StringBuilder(); 574 sb.append("mSufficiencyCheckEnabledWhenScreenOff=") 575 .append(mSufficiencyCheckEnabledWhenScreenOff) 576 .append(", mSufficiencyCheckEnabledWhenScreenOn=") 577 .append(mSufficiencyCheckEnabledWhenScreenOn) 578 .append(", mAssociatedNetworkSelectionOverride=") 579 .append(mAssociatedNetworkSelectionOverride) 580 .append(", mUserConnectChoiceOverrideEnabled=") 581 .append(mUserConnectChoiceOverrideEnabled) 582 .append(", mLastSelectionWeightEnabled=") 583 .append(mLastSelectionWeightEnabled) 584 .append(", mRssi2Thresholds=") 585 .append(Arrays.toString(mRssi2Thresholds)) 586 .append(", mRssi5Thresholds=") 587 .append(Arrays.toString(mRssi5Thresholds)) 588 .append(", mRssi6Thresholds=") 589 .append(Arrays.toString(mRssi6Thresholds)) 590 .append(", mFrequencyWeights=") 591 .append(mFrequencyWeights.toString()); 592 return sb.toString(); 593 } 594 } 595