blob: 71c7544a3a4cc59b1f7952596eaf93e23d23541a [file] [log] [blame]
Al Suttonb0067fb2019-08-16 10:34:46 +01001/*
2 * Copyright (C) 2019 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
17package android.provider.settings.validators;
18
19import android.annotation.Nullable;
20import android.content.ComponentName;
21import android.net.Uri;
22import android.text.TextUtils;
23
24import org.json.JSONException;
25import org.json.JSONObject;
26
Al Sutton91f89d02019-08-16 12:56:57 +010027import java.text.SimpleDateFormat;
Al Suttonb0067fb2019-08-16 10:34:46 +010028import java.util.Locale;
29
30/**
31 * This class provides both interface for validation and common validators
32 * used to ensure Settings have meaningful values.
33 *
34 * @hide
35 */
36public class SettingsValidators {
37
38 public static final Validator BOOLEAN_VALIDATOR =
39 new DiscreteValueValidator(new String[] {"0", "1"});
40
41 public static final Validator ANY_STRING_VALIDATOR = new Validator() {
42 @Override
43 public boolean validate(@Nullable String value) {
44 return true;
45 }
46 };
47
48 public static final Validator NON_NEGATIVE_INTEGER_VALIDATOR = new Validator() {
49 @Override
50 public boolean validate(@Nullable String value) {
51 try {
52 return Integer.parseInt(value) >= 0;
53 } catch (NumberFormatException e) {
54 return false;
55 }
56 }
57 };
58
59 public static final Validator ANY_INTEGER_VALIDATOR = new Validator() {
60 @Override
61 public boolean validate(@Nullable String value) {
62 try {
63 Integer.parseInt(value);
64 return true;
65 } catch (NumberFormatException e) {
66 return false;
67 }
68 }
69 };
70
71 public static final Validator URI_VALIDATOR = new Validator() {
72 @Override
73 public boolean validate(@Nullable String value) {
74 try {
75 Uri.decode(value);
76 return true;
77 } catch (IllegalArgumentException e) {
78 return false;
79 }
80 }
81 };
82
83 /**
84 * Does not allow a setting to have a null {@link ComponentName}. Use {@link
85 * SettingsValidators#NULLABLE_COMPONENT_NAME_VALIDATOR} instead if a setting can have a
86 * nullable {@link ComponentName}.
87 */
88 public static final Validator COMPONENT_NAME_VALIDATOR = new Validator() {
89 @Override
90 public boolean validate(@Nullable String value) {
91 return value != null && ComponentName.unflattenFromString(value) != null;
92 }
93 };
94
95 /**
96 * Allows a setting to have a null {@link ComponentName}.
97 */
98 public static final Validator NULLABLE_COMPONENT_NAME_VALIDATOR = new Validator() {
99 @Override
100 public boolean validate(@Nullable String value) {
101 return value == null || COMPONENT_NAME_VALIDATOR.validate(value);
102 }
103 };
104
105 public static final Validator PACKAGE_NAME_VALIDATOR = new Validator() {
106 @Override
107 public boolean validate(@Nullable String value) {
108 return value != null && isStringPackageName(value);
109 }
110
111 private boolean isStringPackageName(String value) {
112 // The name may contain uppercase or lowercase letters ('A' through 'Z'), numbers,
113 // and underscores ('_'). However, individual package name parts may only
114 // start with letters.
115 // (https://developer.android.com/guide/topics/manifest/manifest-element.html#package)
116 if (value == null) {
117 return false;
118 }
119 String[] subparts = value.split("\\.");
120 boolean isValidPackageName = true;
121 for (String subpart : subparts) {
122 isValidPackageName &= isSubpartValidForPackageName(subpart);
123 if (!isValidPackageName) break;
124 }
125 return isValidPackageName;
126 }
127
128 private boolean isSubpartValidForPackageName(String subpart) {
129 if (subpart.length() == 0) return false;
130 boolean isValidSubpart = Character.isLetter(subpart.charAt(0));
131 for (int i = 1; i < subpart.length(); i++) {
132 isValidSubpart &= (Character.isLetterOrDigit(subpart.charAt(i))
133 || (subpart.charAt(i) == '_'));
134 if (!isValidSubpart) break;
135 }
136 return isValidSubpart;
137 }
138 };
139
140 public static final Validator LENIENT_IP_ADDRESS_VALIDATOR = new Validator() {
141 private static final int MAX_IPV6_LENGTH = 45;
142
143 @Override
144 public boolean validate(@Nullable String value) {
145 if (value == null) {
146 return false;
147 }
148 return value.length() <= MAX_IPV6_LENGTH;
149 }
150 };
151
152 public static final Validator LOCALE_VALIDATOR = new Validator() {
153 @Override
154 public boolean validate(@Nullable String value) {
155 if (value == null) {
156 return false;
157 }
158 Locale[] validLocales = Locale.getAvailableLocales();
159 for (Locale locale : validLocales) {
160 if (value.equals(locale.toString())) {
161 return true;
162 }
163 }
164 return false;
165 }
166 };
167
168 /** {@link Validator} that checks whether a value is a valid {@link JSONObject}. */
169 public static final Validator JSON_OBJECT_VALIDATOR = (value) -> {
170 if (TextUtils.isEmpty(value)) {
171 return false;
172 }
173 try {
174 new JSONObject(value);
175 return true;
176 } catch (JSONException e) {
177 return false;
178 }
179 };
180
181 public static final Validator TTS_LIST_VALIDATOR = new TTSListValidator();
182
183 public static final Validator TILE_LIST_VALIDATOR = new TileListValidator();
Al Sutton91f89d02019-08-16 12:56:57 +0100184
185 static final Validator DATE_FORMAT_VALIDATOR = value -> {
186 try {
187 new SimpleDateFormat(value);
188 return true;
189 } catch (IllegalArgumentException | NullPointerException e) {
190 return false;
191 }
192 };
193
194 static final Validator COLON_SEPARATED_COMPONENT_LIST_VALIDATOR =
195 new ComponentNameListValidator(":");
196
197 static final Validator COLON_SEPARATED_PACKAGE_LIST_VALIDATOR =
198 new PackageNameListValidator(":");
199
200 static final Validator COMMA_SEPARATED_COMPONENT_LIST_VALIDATOR =
201 new ComponentNameListValidator(",");
202
203 static final Validator PERCENTAGE_INTEGER_VALIDATOR =
204 new InclusiveIntegerRangeValidator(0, 100);
205
206 static final Validator VIBRATION_INTENSITY_VALIDATOR = new InclusiveIntegerRangeValidator(0, 3);
Rhed Jaof211ff62019-11-27 22:53:44 +0800207
208 static final Validator ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR =
209 new AccessibilityShortcutTargetListValidator();
Al Suttonb0067fb2019-08-16 10:34:46 +0100210}