| /* |
| * Copyright (C) 2019 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.provider.settings.validators; |
| |
| import android.annotation.Nullable; |
| import android.content.ComponentName; |
| import android.net.Uri; |
| import android.text.TextUtils; |
| |
| import org.json.JSONException; |
| import org.json.JSONObject; |
| |
| import java.text.SimpleDateFormat; |
| import java.util.Locale; |
| |
| /** |
| * This class provides both interface for validation and common validators |
| * used to ensure Settings have meaningful values. |
| * |
| * @hide |
| */ |
| public class SettingsValidators { |
| |
| public static final Validator BOOLEAN_VALIDATOR = |
| new DiscreteValueValidator(new String[] {"0", "1"}); |
| |
| public static final Validator ANY_STRING_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| return true; |
| } |
| }; |
| |
| public static final Validator NON_NEGATIVE_INTEGER_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| try { |
| return Integer.parseInt(value) >= 0; |
| } catch (NumberFormatException e) { |
| return false; |
| } |
| } |
| }; |
| |
| public static final Validator ANY_INTEGER_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| try { |
| Integer.parseInt(value); |
| return true; |
| } catch (NumberFormatException e) { |
| return false; |
| } |
| } |
| }; |
| |
| public static final Validator URI_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| try { |
| Uri.decode(value); |
| return true; |
| } catch (IllegalArgumentException e) { |
| return false; |
| } |
| } |
| }; |
| |
| /** |
| * Does not allow a setting to have a null {@link ComponentName}. Use {@link |
| * SettingsValidators#NULLABLE_COMPONENT_NAME_VALIDATOR} instead if a setting can have a |
| * nullable {@link ComponentName}. |
| */ |
| public static final Validator COMPONENT_NAME_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| return value != null && ComponentName.unflattenFromString(value) != null; |
| } |
| }; |
| |
| /** |
| * Allows a setting to have a null {@link ComponentName}. |
| */ |
| public static final Validator NULLABLE_COMPONENT_NAME_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| return value == null || COMPONENT_NAME_VALIDATOR.validate(value); |
| } |
| }; |
| |
| public static final Validator PACKAGE_NAME_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| return value != null && isStringPackageName(value); |
| } |
| |
| private boolean isStringPackageName(String value) { |
| // The name may contain uppercase or lowercase letters ('A' through 'Z'), numbers, |
| // and underscores ('_'). However, individual package name parts may only |
| // start with letters. |
| // (https://developer.android.com/guide/topics/manifest/manifest-element.html#package) |
| if (value == null) { |
| return false; |
| } |
| String[] subparts = value.split("\\."); |
| boolean isValidPackageName = true; |
| for (String subpart : subparts) { |
| isValidPackageName &= isSubpartValidForPackageName(subpart); |
| if (!isValidPackageName) break; |
| } |
| return isValidPackageName; |
| } |
| |
| private boolean isSubpartValidForPackageName(String subpart) { |
| if (subpart.length() == 0) return false; |
| boolean isValidSubpart = Character.isLetter(subpart.charAt(0)); |
| for (int i = 1; i < subpart.length(); i++) { |
| isValidSubpart &= (Character.isLetterOrDigit(subpart.charAt(i)) |
| || (subpart.charAt(i) == '_')); |
| if (!isValidSubpart) break; |
| } |
| return isValidSubpart; |
| } |
| }; |
| |
| public static final Validator LENIENT_IP_ADDRESS_VALIDATOR = new Validator() { |
| private static final int MAX_IPV6_LENGTH = 45; |
| |
| @Override |
| public boolean validate(@Nullable String value) { |
| if (value == null) { |
| return false; |
| } |
| return value.length() <= MAX_IPV6_LENGTH; |
| } |
| }; |
| |
| public static final Validator LOCALE_VALIDATOR = new Validator() { |
| @Override |
| public boolean validate(@Nullable String value) { |
| if (value == null) { |
| return false; |
| } |
| Locale[] validLocales = Locale.getAvailableLocales(); |
| for (Locale locale : validLocales) { |
| if (value.equals(locale.toString())) { |
| return true; |
| } |
| } |
| return false; |
| } |
| }; |
| |
| /** {@link Validator} that checks whether a value is a valid {@link JSONObject}. */ |
| public static final Validator JSON_OBJECT_VALIDATOR = (value) -> { |
| if (TextUtils.isEmpty(value)) { |
| return false; |
| } |
| try { |
| new JSONObject(value); |
| return true; |
| } catch (JSONException e) { |
| return false; |
| } |
| }; |
| |
| public static final Validator TTS_LIST_VALIDATOR = new TTSListValidator(); |
| |
| public static final Validator TILE_LIST_VALIDATOR = new TileListValidator(); |
| |
| static final Validator DATE_FORMAT_VALIDATOR = value -> { |
| try { |
| new SimpleDateFormat(value); |
| return true; |
| } catch (IllegalArgumentException | NullPointerException e) { |
| return false; |
| } |
| }; |
| |
| static final Validator COLON_SEPARATED_COMPONENT_LIST_VALIDATOR = |
| new ComponentNameListValidator(":"); |
| |
| static final Validator COLON_SEPARATED_PACKAGE_LIST_VALIDATOR = |
| new PackageNameListValidator(":"); |
| |
| static final Validator COMMA_SEPARATED_COMPONENT_LIST_VALIDATOR = |
| new ComponentNameListValidator(","); |
| |
| static final Validator PERCENTAGE_INTEGER_VALIDATOR = |
| new InclusiveIntegerRangeValidator(0, 100); |
| |
| static final Validator VIBRATION_INTENSITY_VALIDATOR = new InclusiveIntegerRangeValidator(0, 3); |
| |
| static final Validator ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR = |
| new AccessibilityShortcutTargetListValidator(); |
| } |