1 /* 2 * Copyright 2023 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.google.android.iwlan; 18 19 import android.content.Context; 20 import android.os.PersistableBundle; 21 import android.support.annotation.IntDef; 22 import android.support.annotation.NonNull; 23 import android.telephony.CarrierConfigManager; 24 import android.telephony.SubscriptionManager; 25 26 import androidx.annotation.VisibleForTesting; 27 28 /** Class for handling IWLAN carrier configuration. */ 29 public class IwlanCarrierConfig { 30 static final String PREFIX = "iwlan."; 31 32 /** 33 * Key for setting the delay in seconds to release the IWLAN connection after a handover to 34 * WWAN. Refer to {@link #DEFAULT_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT} for the default 35 * value. 36 */ 37 public static final String KEY_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT = 38 PREFIX + "handover_to_wwan_release_delay_second_int"; 39 40 /** 41 * Key to exclude IKE N1_MODE_CAPABILITY Notify payload during emergency session setup without 42 * affecting normal sessions. See {@link #DEFAULT_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL} 43 * for the default value. 44 */ 45 public static final String KEY_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL = 46 PREFIX + "n1_mode_exclusion_for_emergency_session_bool"; 47 48 /** 49 * Key to decide whether N1 mode shall be enabled or disabled depending on 5G enabling status 50 * via the UI/UX. See {@link #DEFAULT_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL} for the default value. 51 */ 52 public static final String KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL = 53 PREFIX + "update_n1_mode_on_ui_change_bool"; 54 55 /** 56 * Boolean indicating if distinct ePDG selection for emergency sessions is enabled. Refer to 57 * {@link #DEFAULT_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL} for the default value. 58 */ 59 public static final String KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL = 60 PREFIX + "distinct_epdg_for_emergency_allowed_bool"; 61 62 /** 63 * Key to control whether the UE includes the IKE DEVICE_IDENTITY Notify payload when receiving 64 * a request. See {@link #DEFAULT_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL} for the default value. 65 */ 66 public static final String KEY_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL = 67 PREFIX + "ike_device_identity_supported_bool"; 68 69 /** 70 * Boolean indicating if reordering ike SA transforms enabled. Refer to {@link 71 * #DEFAULT_IKE_SA_TRANSFORMS_REORDER_BOOL} for the default value. 72 */ 73 public static final String KEY_IKE_SA_TRANSFORMS_REORDER_BOOL = 74 PREFIX + "ike_sa_transforms_reorder_bool"; 75 76 /** Trigger network validation when making a call */ 77 public static final int NETWORK_VALIDATION_EVENT_MAKING_CALL = 0; 78 79 /** Trigger network validation when screen on */ 80 public static final int NETWORK_VALIDATION_EVENT_SCREEN_ON = 1; 81 82 /** Trigger network validation when no response on network */ 83 public static final int NETWORK_VALIDATION_EVENT_NO_RESPONSE = 2; 84 85 @IntDef({ 86 NETWORK_VALIDATION_EVENT_MAKING_CALL, 87 NETWORK_VALIDATION_EVENT_SCREEN_ON, 88 NETWORK_VALIDATION_EVENT_NO_RESPONSE 89 }) 90 public @interface NetworkValidationEvent {} 91 92 /** 93 * Key to control which events should trigger IWLAN underlying network validation when specific 94 * event received, possible values in the int array: 95 * 96 * <ul> 97 * <li>0: NETWORK_VALIDATION_EVENT_MAKING_CALL 98 * <li>1: NETWORK_VALIDATION_EVENT_SCREEN_ON 99 * <li>2: NETWORK_VALIDATION_EVENT_NO_RESPONSE 100 * </ul> 101 */ 102 public static final String KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY = 103 PREFIX + "underlying_network_validation_events_int_array"; 104 105 /** 106 * IWLAN error policy configs that determine the behavior when error happens during ePDG tunnel 107 * setup. Refer to {@link #DEFAULT_ERROR_POLICY_CONFIG_STRING} for the default value. 108 * 109 * <p>The Error Config is defined as an Array of APNs identified by "ApnName". Other than Apn 110 * names this can also have "*" value which represents that this can be used as a generic 111 * fallback when no other policy matches. 112 * 113 * <p>Each APN associated with "ApnName" has an array of "ErrorTypes". Where each element in 114 * "ErrorTypes" array defines the config for the Error. The element in "ErrorTypes" array has 115 * the following items: 116 * 117 * <ul> 118 * <li>"ErrorType": The type of error in String. Possible error types are: 119 * <ol> 120 * <li>"IKE_PROTOCOL_ERROR_TYPE" refers to the Notify Error coming in Notify payload. 121 * See https://tools.ietf.org/html/rfc4306#section-3.10.1 for global errors and 122 * carrier specific requirements for other carrier specific error codes. 123 * <li>"GENERIC_ERROR_TYPE" refers to the following IWLAN errors - "IO_EXCEPTION", 124 * "TIMEOUT_EXCEPTION", "SERVER_SELECTION_FAILED" and "TUNNEL_TRANSFORM_FAILED". 125 * <li>"*" represents that this policy is a generic fallback when no other policy 126 * matches. 127 * </ol> 128 * <li>"ErrorDetails": Array of errors specifics for which the policy needs to be applied to. 129 * Note: Array can be a mix of numbers, ranges and string formats. Following are the 130 * currently supported formats of elements in the array: 131 * <ol> 132 * <li>Number or Code: "24" - Number specific to the error. 133 * <li>Range: "9000-9050" - Range of specific errors. 134 * <li>Any: "*" value represents that this can be applied to all ErrorDetails when there 135 * is no specific match. This will be a single element array. 136 * <li>String: String describing the specific error. Current allowed string values - 137 * "IO_EXCEPTION", "TIMEOUT_EXCEPTION", "SERVER_SELECTION_FAILED" and 138 * "TUNNEL_TRANSFORM_FAILED" 139 * </ol> 140 * <p>"IKE_PROTOCOL_EXCEPTION" ErrorType expects the "error_detail" to be defined only in 141 * numbers or range of numbers. Examples: ["24"] or ["9000-9050"] or ["7", "14000-14050"] 142 * <p>"GENERIC_ERROR_TYPE" or "*" ErrorType expects only the following to be in 143 * "ErrorDetails" - "IO_EXCEPTION", "TIMEOUT_EXCEPTION", "SERVER_SELECTION_FAILED", 144 * "TUNNEL_TRANSFORM_FAILED" and "*". Examples: ["IO_EXCEPTION", "TIMEOUT_EXCEPTION"] or 145 * ["*"] 146 * <li>"RetryArray": Array of retry times (in secs) represented in string format. Following 147 * formats are currently supported: 148 * <ol> 149 * <li>["0","0", "0"] Retry immediately for maximum 3 times and then fail. 150 * <li>[] Empty array means to fail whenever the error happens. 151 * <li>["2", "4", "8"] Retry times are 2 secs, 4secs and 8 secs - fail after that. 152 * <li>["5", "10", "15", "-1"] Here the "-1" represents infinite retires with the retry 153 * time "15" the last retry number). 154 * <li>["2+r15"] 2 seconds + random time below 15 seconds, fail after that. 155 * </ol> 156 * <p>When fails, by default throttle for 24 hours. 157 * <li>"UnthrottlingEvents": Events for which the retry time can be unthrottled in string. 158 * Possible unthrottling events are: 159 * <ol> 160 * <li>"WIFI_DISABLE_EVENT": Wifi on to off toggle. 161 * <li>"APM_DISABLE_EVENT": APM on to off toggle. 162 * <li>"APM_ENABLE_EVENT": APM off to on toggle. 163 * <li>"WIFI_AP_CHANGED_EVENT": Wifi is connected to an AP with different SSID. 164 * <li>"WIFI_CALLING_DISABLE_EVENT": Wifi calling button on to off toggle. 165 * </ol> 166 * <li>"NumAttemptsPerFqdn" Integer to specify th count of tunnel setup attempts IWLAN must 167 * perform with the IP address(es) returned by a single FQDN, before moving on to the next 168 * FQDN. It is an optional field. 169 * <li>"HandoverAttemptCount": Integer to specify the number of handover request attempts 170 * before using initial attach instead. It is an optional field. 171 * <p>"HandoverAttemptCount" should not be defined in the config when "ErrorType" is 172 * defined as any other error types except "IKE_PROTOCOL_ERROR_TYPE", including "*". 173 * </ul> 174 * 175 * <p>Note: When the value is "*" for any of "ApnName" or "ErrorType" or "ErrorDetails", it 176 * means that the config definition applies to rest of the errors for which the config is not 177 * defined. For example, if "ApnName" is "ims" and one of the "ErrorType" in it is defined as 178 * "*" - this policy will be applied to the error that doesn't fall into other error types 179 * defined under "ims". 180 */ 181 public static final String KEY_ERROR_POLICY_CONFIG_STRING = 182 PREFIX + "key_error_policy_config_string"; 183 184 /** 185 * Default delay in seconds for releasing the IWLAN connection after a WWAN handover. This is 186 * the default value for {@link #KEY_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT}. 187 */ 188 public static final int DEFAULT_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT = 0; 189 190 /** 191 * The default value for determining whether the IKE N1_MODE_CAPABILITY Notify payload is 192 * excluded during emergency session setup. 193 */ 194 public static final boolean DEFAULT_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL = false; 195 196 /** 197 * The default value for determining whether N1 mode shall be enabled or disabled depending on 198 * 5G enabling status via the UI/UX. 199 */ 200 public static final boolean DEFAULT_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL = false; 201 202 /** This is the default value for {@link #KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL}. */ 203 public static final boolean DEFAULT_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL = false; 204 205 /** 206 * Default value indicating whether the UE includes the IKE DEVICE_IDENTITY Notify payload upon 207 * receiving a request. This is the default setting for {@link 208 * #KEY_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL}. 209 */ 210 public static final boolean DEFAULT_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL = false; 211 212 /** This is the default value for {@link #KEY_IKE_SA_TRANSFORMS_REORDER_BOOL}. */ 213 public static final boolean DEFAULT_IKE_SA_TRANSFORMS_REORDER_BOOL = false; 214 215 /** 216 * The default value of which events should trigger IWLAN underlying network validation. This is 217 * the default value for {@link #KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY} 218 */ 219 public static final int[] DEFAULT_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY = {}; 220 221 /** 222 * The default value for determining IWLAN's behavior when error happens during ePDG tunnel 223 * setup. This is the default value for {@link #KEY_ERROR_POLICY_CONFIG_STRING}. 224 */ 225 public static final String DEFAULT_ERROR_POLICY_CONFIG_STRING = 226 """ 227 [{ 228 "ApnName": "*", 229 "ErrorTypes": [{ 230 "ErrorType": "*", 231 "ErrorDetails": ["*"], 232 "RetryArray": ["1","2","2","10","20","40","80","160", 233 "320","640","1280","1800","3600","-1"], 234 "UnthrottlingEvents": ["APM_ENABLE_EVENT","APM_DISABLE_EVENT", 235 "WIFI_DISABLE_EVENT","WIFI_AP_CHANGED_EVENT"]},{ 236 "ErrorType": "GENERIC_ERROR_TYPE", 237 "ErrorDetails": ["IO_EXCEPTION"], 238 "RetryArray": ["0","0","0","30","60+r15","120","-1"], 239 "UnthrottlingEvents": ["APM_ENABLE_EVENT","APM_DISABLE_EVENT", 240 "WIFI_DISABLE_EVENT","WIFI_AP_CHANGED_EVENT"]},{ 241 "ErrorType": "IKE_PROTOCOL_ERROR_TYPE", 242 "ErrorDetails": ["*"], 243 "RetryArray": ["5","10","10","20","40","80","160", 244 "320","640","1280","1800","3600","-1"], 245 "UnthrottlingEvents": ["APM_ENABLE_EVENT","WIFI_DISABLE_EVENT", 246 "WIFI_CALLING_DISABLE_EVENT"]},{ 247 "ErrorType": "IKE_PROTOCOL_ERROR_TYPE", 248 "ErrorDetails": ["36"], 249 "RetryArray": ["0","0","0","10","20","40","80","160", 250 "320","640","1280","1800","3600","-1"], 251 "UnthrottlingEvents": ["APM_ENABLE_EVENT","WIFI_DISABLE_EVENT", 252 "WIFI_CALLING_DISABLE_EVENT"], 253 "HandoverAttemptCount": "3"}] 254 }] 255 """; 256 257 private static final PersistableBundle sTestBundle = new PersistableBundle(); 258 259 private static PersistableBundle sHiddenBundle = new PersistableBundle(); 260 261 static { 262 sHiddenBundle = createHiddenDefaultConfig(); 263 } 264 265 /** 266 * Creates a hidden default configuration. 267 * 268 * @return a PersistableBundle containing the hidden default configuration 269 */ createHiddenDefaultConfig()270 private static @NonNull PersistableBundle createHiddenDefaultConfig() { 271 PersistableBundle bundle = new PersistableBundle(); 272 bundle.putInt( 273 KEY_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT, 274 DEFAULT_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT); 275 bundle.putBoolean( 276 KEY_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL, 277 DEFAULT_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL); 278 bundle.putBoolean( 279 KEY_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL, DEFAULT_UPDATE_N1_MODE_ON_UI_CHANGE_BOOL); 280 bundle.putBoolean( 281 KEY_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL, 282 DEFAULT_DISTINCT_EPDG_FOR_EMERGENCY_ALLOWED_BOOL); 283 bundle.putBoolean( 284 KEY_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL, DEFAULT_IKE_DEVICE_IDENTITY_SUPPORTED_BOOL); 285 bundle.putBoolean( 286 KEY_IKE_SA_TRANSFORMS_REORDER_BOOL, DEFAULT_IKE_SA_TRANSFORMS_REORDER_BOOL); 287 bundle.putIntArray( 288 KEY_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY, 289 DEFAULT_UNDERLYING_NETWORK_VALIDATION_EVENTS_INT_ARRAY); 290 bundle.putString(KEY_ERROR_POLICY_CONFIG_STRING, DEFAULT_ERROR_POLICY_CONFIG_STRING); 291 return bundle; 292 } 293 getConfig(Context context, int slotId, String key)294 private static PersistableBundle getConfig(Context context, int slotId, String key) { 295 if (sTestBundle.containsKey(key)) { 296 return sTestBundle; 297 } 298 299 CarrierConfigManager carrierConfigManager = 300 context.getSystemService(CarrierConfigManager.class); 301 if (carrierConfigManager == null) { 302 return getDefaultConfig(key); 303 } 304 305 int subId = IwlanHelper.getSubId(context, slotId); 306 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 307 return getDefaultConfig(key); 308 } 309 310 try { 311 PersistableBundle bundle = carrierConfigManager.getConfigForSubId(subId, key); 312 return bundle.containsKey(key) ? bundle : getDefaultConfig(key); 313 } catch (IllegalStateException e) { 314 // Fall through to return default config 315 } 316 317 return getDefaultConfig(key); 318 } 319 getDefaultConfig(String key)320 private static PersistableBundle getDefaultConfig(String key) { 321 PersistableBundle bundle = CarrierConfigManager.getDefaultConfig(); 322 if (bundle.containsKey(key)) { 323 return bundle; 324 } 325 326 if (sHiddenBundle.containsKey(key)) { 327 return sHiddenBundle; 328 } 329 330 throw new IllegalArgumentException("Default config not found for key: " + key); 331 } 332 333 /** 334 * Returns whether CarrierConfig is loaded for the given slot ID. 335 * 336 * @param context the application context 337 * @param slotId the slot ID 338 * @return Returns {@code true} if the CarrierConfig for the given slot ID is loaded. 339 */ isCarrierConfigLoaded(Context context, int slotId)340 static boolean isCarrierConfigLoaded(Context context, int slotId) { 341 int subId = IwlanHelper.getSubId(context, slotId); 342 343 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 344 // Fail to query subscription id, just return false. 345 return false; 346 } 347 348 CarrierConfigManager carrierConfigManager = 349 context.getSystemService(CarrierConfigManager.class); 350 PersistableBundle bundle; 351 try { 352 bundle = 353 carrierConfigManager != null 354 ? carrierConfigManager.getConfigForSubId( 355 subId, CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL) 356 : new PersistableBundle(); 357 } catch (Exception e) { 358 bundle = new PersistableBundle(); 359 } 360 361 return CarrierConfigManager.isConfigForIdentifiedCarrier(bundle); 362 } 363 364 /** 365 * Gets a configuration int value for a given slot ID and key. 366 * 367 * @param context the application context 368 * @param slotId the slot ID 369 * @param key the configuration key 370 * @return the configuration int value 371 */ getConfigInt(Context context, int slotId, String key)372 public static int getConfigInt(Context context, int slotId, String key) { 373 return getConfig(context, slotId, key).getInt(key); 374 } 375 376 /** 377 * Gets a configuration long value for a given slot ID and key. 378 * 379 * @param context the application context 380 * @param slotId the slot ID 381 * @param key the configuration key 382 * @return the configuration long value 383 */ getConfigLong(Context context, int slotId, String key)384 public static long getConfigLong(Context context, int slotId, String key) { 385 return getConfig(context, slotId, key).getLong(key); 386 } 387 388 /** 389 * Gets a configuration double value for a given slot ID and key. 390 * 391 * @param context the application context 392 * @param slotId the slot ID 393 * @param key the configuration key 394 * @return the configuration double value 395 */ getConfigDouble(Context context, int slotId, String key)396 public static double getConfigDouble(Context context, int slotId, String key) { 397 return getConfig(context, slotId, key).getDouble(key); 398 } 399 400 /** 401 * Gets a configuration boolean value for a given slot ID and key. 402 * 403 * @param context the application context 404 * @param slotId the slot ID 405 * @param key the configuration key 406 * @return the configuration boolean value 407 */ getConfigBoolean(Context context, int slotId, String key)408 public static boolean getConfigBoolean(Context context, int slotId, String key) { 409 return getConfig(context, slotId, key).getBoolean(key); 410 } 411 412 /** 413 * Gets a configuration string value for a given slot ID and key. 414 * 415 * @param context the application context 416 * @param slotId the slot ID 417 * @param key the configuration key 418 * @return the configuration string value 419 */ getConfigString(Context context, int slotId, String key)420 public static String getConfigString(Context context, int slotId, String key) { 421 return getConfig(context, slotId, key).getString(key); 422 } 423 424 /** 425 * Gets a configuration int[] value for a given slot ID and key. 426 * 427 * @param context the application context 428 * @param slotId the slot ID 429 * @param key the configuration key 430 * @return the configuration int[] value 431 */ getConfigIntArray(Context context, int slotId, String key)432 public static int[] getConfigIntArray(Context context, int slotId, String key) { 433 return getConfig(context, slotId, key).getIntArray(key); 434 } 435 436 /** 437 * Gets a configuration long[] value for a given slot ID and key. 438 * 439 * @param context the application context 440 * @param slotId the slot ID 441 * @param key the configuration key 442 * @return the configuration long[] value 443 */ getConfigLongArray(Context context, int slotId, String key)444 public static long[] getConfigLongArray(Context context, int slotId, String key) { 445 return getConfig(context, slotId, key).getLongArray(key); 446 } 447 448 /** 449 * Gets a configuration double[] value for a given slot ID and key. 450 * 451 * @param context the application context 452 * @param slotId the slot ID 453 * @param key the configuration key 454 * @return the configuration double[] value 455 */ getConfigDoubleArray(Context context, int slotId, String key)456 public static double[] getConfigDoubleArray(Context context, int slotId, String key) { 457 return getConfig(context, slotId, key).getDoubleArray(key); 458 } 459 460 /** 461 * Gets a configuration boolean[] value for a given slot ID and key. 462 * 463 * @param context the application context 464 * @param slotId the slot ID 465 * @param key the configuration key 466 * @return the configuration boolean[] value 467 */ getConfigBooleanArray(Context context, int slotId, String key)468 public static boolean[] getConfigBooleanArray(Context context, int slotId, String key) { 469 return getConfig(context, slotId, key).getBooleanArray(key); 470 } 471 472 /** 473 * Gets a configuration string[] value for a given slot ID and key. 474 * 475 * @param context the application context 476 * @param slotId the slot ID 477 * @param key the configuration key 478 * @return the configuration string[] value 479 */ getConfigStringArray(Context context, int slotId, String key)480 public static String[] getConfigStringArray(Context context, int slotId, String key) { 481 return getConfig(context, slotId, key).getStringArray(key); 482 } 483 484 /** 485 * Gets the default configuration int value for a given key. 486 * 487 * @param key the configuration key 488 * @return the default configuration int value 489 * @throws IllegalArgumentException if the default configuration is null for the given key 490 */ getDefaultConfigInt(String key)491 public static int getDefaultConfigInt(String key) { 492 return getDefaultConfig(key).getInt(key); 493 } 494 495 /** 496 * Gets the default configuration long value for a given key. 497 * 498 * @param key the configuration key 499 * @return the default configuration long value 500 * @throws IllegalArgumentException if the default configuration is null for the given key 501 */ getDefaultConfigLong(String key)502 public static long getDefaultConfigLong(String key) { 503 return getDefaultConfig(key).getLong(key); 504 } 505 506 /** 507 * Gets the default configuration double value for a given key. 508 * 509 * @param key the configuration key 510 * @return the default configuration double value 511 * @throws IllegalArgumentException if the default configuration is null for the given key 512 */ getDefaultConfigDouble(String key)513 public static double getDefaultConfigDouble(String key) { 514 return getDefaultConfig(key).getDouble(key); 515 } 516 517 /** 518 * Gets the default configuration string value for a given key. 519 * 520 * @param key the configuration key 521 * @return the default configuration string value 522 * @throws IllegalArgumentException if the default configuration is null for the given key 523 */ getDefaultConfigString(String key)524 public static String getDefaultConfigString(String key) { 525 return getDefaultConfig(key).getString(key); 526 } 527 528 /** 529 * Gets the default configuration boolean value for a given key. 530 * 531 * @param key the configuration key 532 * @return the default configuration boolean value 533 * @throws IllegalArgumentException if the default configuration is null for the given key 534 */ getDefaultConfigBoolean(String key)535 public static boolean getDefaultConfigBoolean(String key) { 536 return getDefaultConfig(key).getBoolean(key); 537 } 538 539 /** 540 * Gets the default configuration int[] value for a given key. 541 * 542 * @param key the configuration key 543 * @return the default configuration int[] value 544 * @throws IllegalArgumentException if the default configuration is null for the given key 545 */ getDefaultConfigIntArray(String key)546 public static int[] getDefaultConfigIntArray(String key) { 547 return getDefaultConfig(key).getIntArray(key); 548 } 549 550 /** 551 * Gets the default configuration long value for a given key. 552 * 553 * @param key the configuration key 554 * @return the default configuration long value 555 * @throws IllegalArgumentException if the default configuration is null for the given key 556 */ getDefaultConfigLongArray(String key)557 public static long[] getDefaultConfigLongArray(String key) { 558 return getDefaultConfig(key).getLongArray(key); 559 } 560 561 /** 562 * Gets the default configuration double[] value for a given key. 563 * 564 * @param key the configuration key 565 * @return the default configuration double[] value 566 * @throws IllegalArgumentException if the default configuration is null for the given key 567 */ getDefaultConfigDoubleArray(String key)568 public static double[] getDefaultConfigDoubleArray(String key) { 569 return getDefaultConfig(key).getDoubleArray(key); 570 } 571 572 /** 573 * Gets the default configuration string[] value for a given key. 574 * 575 * @param key the configuration key 576 * @return the default configuration string[] value 577 * @throws IllegalArgumentException if the default configuration is null for the given key 578 */ getDefaultConfigStringArray(String key)579 public static String[] getDefaultConfigStringArray(String key) { 580 return getDefaultConfig(key).getStringArray(key); 581 } 582 583 /** 584 * Gets the default configuration boolean[] value for a given key. 585 * 586 * @param key the configuration key 587 * @return the default configuration boolean[] value 588 * @throws IllegalArgumentException if the default configuration is null for the given key 589 */ getDefaultConfigBooleanArray(String key)590 public static boolean[] getDefaultConfigBooleanArray(String key) { 591 return getDefaultConfig(key).getBooleanArray(key); 592 } 593 594 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigBundle(PersistableBundle bundle)595 public static void putTestConfigBundle(PersistableBundle bundle) { 596 sTestBundle.putAll(bundle); 597 } 598 599 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigInt(@onNull String key, int value)600 public static void putTestConfigInt(@NonNull String key, int value) { 601 sTestBundle.putInt(key, value); 602 } 603 604 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigLong(@onNull String key, long value)605 public static void putTestConfigLong(@NonNull String key, long value) { 606 sTestBundle.putLong(key, value); 607 } 608 609 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigDouble(@onNull String key, double value)610 public static void putTestConfigDouble(@NonNull String key, double value) { 611 sTestBundle.putDouble(key, value); 612 } 613 614 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigBoolean(@onNull String key, boolean value)615 public static void putTestConfigBoolean(@NonNull String key, boolean value) { 616 sTestBundle.putBoolean(key, value); 617 } 618 619 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigString(@onNull String key, String value)620 public static void putTestConfigString(@NonNull String key, String value) { 621 sTestBundle.putString(key, value); 622 } 623 624 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigIntArray(@onNull String key, @NonNull int[] value)625 public static void putTestConfigIntArray(@NonNull String key, @NonNull int[] value) { 626 sTestBundle.putIntArray(key, value); 627 } 628 629 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigLongArray(@onNull String key, @NonNull long[] value)630 public static void putTestConfigLongArray(@NonNull String key, @NonNull long[] value) { 631 sTestBundle.putLongArray(key, value); 632 } 633 634 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigDoubleArray(@onNull String key, @NonNull double[] value)635 public static void putTestConfigDoubleArray(@NonNull String key, @NonNull double[] value) { 636 sTestBundle.putDoubleArray(key, value); 637 } 638 639 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigBooleanArray(@onNull String key, @NonNull boolean[] value)640 public static void putTestConfigBooleanArray(@NonNull String key, @NonNull boolean[] value) { 641 sTestBundle.putBooleanArray(key, value); 642 } 643 644 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) putTestConfigStringArray(@onNull String key, @NonNull String[] value)645 public static void putTestConfigStringArray(@NonNull String key, @NonNull String[] value) { 646 sTestBundle.putStringArray(key, value); 647 } 648 649 @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) resetTestConfig()650 public static void resetTestConfig() { 651 sTestBundle.clear(); 652 } 653 getUnderlyingNetworkValidationEventString( @wlanCarrierConfig.NetworkValidationEvent int event)654 public static String getUnderlyingNetworkValidationEventString( 655 @IwlanCarrierConfig.NetworkValidationEvent int event) { 656 return switch (event) { 657 case IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_MAKING_CALL -> "MAKING_CALL"; 658 case IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_SCREEN_ON -> "SCREEN_ON"; 659 case IwlanCarrierConfig.NETWORK_VALIDATION_EVENT_NO_RESPONSE -> "NO_RESPONSE"; 660 default -> "UNKNOWN"; 661 }; 662 } 663 } 664