1 /*
2  * Copyright (C) 2015 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 package com.android.providers.settings;
17 
18 import android.os.Looper;
19 import android.test.AndroidTestCase;
20 import android.util.Xml;
21 
22 import com.android.modules.utils.TypedXmlSerializer;
23 
24 import com.google.common.base.Strings;
25 
26 import java.io.ByteArrayOutputStream;
27 import java.io.File;
28 import java.io.FileOutputStream;
29 import java.io.PrintStream;
30 
31 public class SettingsStateTest extends AndroidTestCase {
32     public static final String CRAZY_STRING =
33             "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\n\u000b\u000c\r" +
34                     "\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a" +
35                     "\u001b\u001c\u001d\u001e\u001f\u0020" +
36                     "fake_setting_value_1" +
37                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
38                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
39                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
40                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
41                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
42                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
43                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
44                     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
45                     "\u1000 \u2000 \u5000 \u8000 \uc000 \ue000" +
46                     "\ud800\udc00\udbff\udfff" + // surrogate pairs
47                     "\uD800ab\uDC00 " + // broken surrogate pairs
48                     "日本語";
49 
50     private static final String TEST_PACKAGE = "package";
51     private static final String SYSTEM_PACKAGE = "android";
52     private static final String SETTING_NAME = "test_setting";
53 
54     private final Object mLock = new Object();
55 
56     private File mSettingsFile;
57 
58     @Override
setUp()59     protected void setUp() {
60         mSettingsFile = new File(getContext().getCacheDir(), "setting.xml");
61         mSettingsFile.delete();
62     }
63 
testIsBinary()64     public void testIsBinary() {
65         assertFalse(SettingsState.isBinary(" abc 日本語"));
66 
67         for (char ch = 0x20; ch < 0xd800; ch++) {
68             assertFalse("ch=" + Integer.toString(ch, 16),
69                     SettingsState.isBinary(String.valueOf(ch)));
70         }
71         for (char ch = 0xe000; ch < 0xfffe; ch++) {
72             assertFalse("ch=" + Integer.toString(ch, 16),
73                     SettingsState.isBinary(String.valueOf(ch)));
74         }
75 
76         for (char ch = 0x0000; ch < 0x20; ch++) {
77             assertTrue("ch=" + Integer.toString(ch, 16),
78                     SettingsState.isBinary(String.valueOf(ch)));
79         }
80         for (char ch = 0xd800; ch < 0xe000; ch++) {
81             assertTrue("ch=" + Integer.toString(ch, 16),
82                     SettingsState.isBinary(String.valueOf(ch)));
83         }
84         assertTrue(SettingsState.isBinary("\ufffe"));
85         assertTrue(SettingsState.isBinary("\uffff"));
86         try {
87             assertFalse(SettingsState.isBinary(null));
88             fail("NullPointerException expected");
89         } catch (NullPointerException expected) {
90         }
91     }
92 
93     /** Make sure we won't pass invalid characters to XML serializer. */
testWriteReadNoCrash()94     public void testWriteReadNoCrash() throws Exception {
95         ByteArrayOutputStream os = new ByteArrayOutputStream();
96 
97         TypedXmlSerializer serializer = Xml.resolveSerializer(os);
98         serializer.startDocument(null, true);
99 
100         for (int ch = 0; ch < 0x10000; ch++) {
101             checkWriteSingleSetting("char=0x" + Integer.toString(ch, 16), serializer,
102                     "key", String.valueOf((char) ch));
103         }
104         checkWriteSingleSetting(serializer, "k", "");
105         checkWriteSingleSetting(serializer, "x", "abc");
106         checkWriteSingleSetting(serializer, "abc", CRAZY_STRING);
107         checkWriteSingleSetting(serializer, "def", null);
108 
109         // Invlid input, but shouoldn't crash.
110         checkWriteSingleSetting(serializer, null, null);
111         checkWriteSingleSetting(serializer, CRAZY_STRING, null);
112         SettingsState.writeSingleSetting(
113                 SettingsState.SETTINGS_VERSION_NEW_ENCODING,
114                 serializer, null, "k", "v", null, "package", null, false, false);
115         SettingsState.writeSingleSetting(
116                 SettingsState.SETTINGS_VERSION_NEW_ENCODING,
117                 serializer, "1", "k", "v", null, null, null, false, false);
118     }
119 
checkWriteSingleSetting(TypedXmlSerializer serializer, String key, String value)120     private void checkWriteSingleSetting(TypedXmlSerializer serializer, String key, String value)
121             throws Exception {
122         checkWriteSingleSetting(key + "/" + value, serializer, key, value);
123     }
124 
checkWriteSingleSetting(String msg, TypedXmlSerializer serializer, String key, String value)125     private void checkWriteSingleSetting(String msg, TypedXmlSerializer serializer,
126             String key, String value) throws Exception {
127         // Make sure the XML serializer won't crash.
128         SettingsState.writeSingleSetting(
129                 SettingsState.SETTINGS_VERSION_NEW_ENCODING,
130                 serializer, "1", key, value, null, "package", null, false, false);
131     }
132 
133     /**
134      * Make sure settings can be written to a file and also can be read.
135      */
testReadWrite()136     public void testReadWrite() {
137         final File file = new File(getContext().getCacheDir(), "setting.xml");
138         file.delete();
139         final Object lock = new Object();
140 
141         final SettingsState ssWriter = new SettingsState(getContext(), lock, file, 1,
142                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
143         ssWriter.setVersionLocked(SettingsState.SETTINGS_VERSION_NEW_ENCODING);
144 
145         ssWriter.insertSettingLocked("k1", "\u0000", null, false, "package");
146         ssWriter.insertSettingLocked("k2", "abc", null, false, "p2");
147         ssWriter.insertSettingLocked("k3", null, null, false, "p2");
148         ssWriter.insertSettingLocked("k4", CRAZY_STRING, null, false, "p3");
149         synchronized (lock) {
150             ssWriter.persistSyncLocked();
151         }
152 
153         final SettingsState ssReader = new SettingsState(getContext(), lock, file, 1,
154                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
155         synchronized (lock) {
156             assertEquals("\u0000", ssReader.getSettingLocked("k1").getValue());
157             assertEquals("abc", ssReader.getSettingLocked("k2").getValue());
158             assertEquals(null, ssReader.getSettingLocked("k3").getValue());
159             assertEquals(CRAZY_STRING, ssReader.getSettingLocked("k4").getValue());
160         }
161     }
162 
163     /**
164      * In version 120, value "null" meant {code NULL}.
165      */
testUpgrade()166     public void testUpgrade() throws Exception {
167         final File file = new File(getContext().getCacheDir(), "setting.xml");
168         file.delete();
169         final Object lock = new Object();
170         final PrintStream os = new PrintStream(new FileOutputStream(file));
171         os.print(
172                 "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" +
173                         "<settings version=\"120\">" +
174                         "  <setting id=\"0\" name=\"k0\" value=\"null\" package=\"null\" />" +
175                         "  <setting id=\"1\" name=\"k1\" value=\"\" package=\"\" />" +
176                         "  <setting id=\"2\" name=\"k2\" value=\"v2\" package=\"p2\" />" +
177                         "</settings>");
178         os.close();
179 
180         final SettingsState ss = new SettingsState(getContext(), lock, file, 1,
181                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
182         synchronized (lock) {
183             SettingsState.Setting s;
184             s = ss.getSettingLocked("k0");
185             assertEquals(null, s.getValue());
186             assertEquals("null", s.getPackageName());
187 
188             s = ss.getSettingLocked("k1");
189             assertEquals("", s.getValue());
190             assertEquals("", s.getPackageName());
191 
192             s = ss.getSettingLocked("k2");
193             assertEquals("v2", s.getValue());
194             assertEquals("p2", s.getPackageName());
195         }
196     }
197 
testInitializeSetting_preserveFlagNotSet()198     public void testInitializeSetting_preserveFlagNotSet() {
199         SettingsState settingsWriter = getSettingStateObject();
200         settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
201         settingsWriter.persistSyncLocked();
202 
203         SettingsState settingsReader = getSettingStateObject();
204         assertFalse(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
205     }
206 
testModifySetting_preserveFlagSet()207     public void testModifySetting_preserveFlagSet() {
208         SettingsState settingsWriter = getSettingStateObject();
209         settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
210         settingsWriter.insertSettingLocked(SETTING_NAME, "2", null, false, TEST_PACKAGE);
211         settingsWriter.persistSyncLocked();
212 
213         SettingsState settingsReader = getSettingStateObject();
214         assertTrue(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
215     }
216 
testModifySettingOverrideableByRestore_preserveFlagNotSet()217     public void testModifySettingOverrideableByRestore_preserveFlagNotSet() {
218         SettingsState settingsWriter = getSettingStateObject();
219         settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
220         settingsWriter.insertSettingLocked(SETTING_NAME, "2", null, false, false, TEST_PACKAGE,
221                 /* overrideableByRestore */ true);
222         settingsWriter.persistSyncLocked();
223 
224         SettingsState settingsReader = getSettingStateObject();
225         assertFalse(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
226     }
227 
testModifySettingOverrideableByRestore_preserveFlagAlreadySet_flagValueUnchanged()228     public void testModifySettingOverrideableByRestore_preserveFlagAlreadySet_flagValueUnchanged() {
229         SettingsState settingsWriter = getSettingStateObject();
230         // Init the setting.
231         settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
232         // This modification will set isValuePreservedInRestore = true.
233         settingsWriter.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
234         // This modification shouldn't change the value of isValuePreservedInRestore since it's
235         // already been set to true.
236         settingsWriter.insertSettingLocked(SETTING_NAME, "2", null, false, false, TEST_PACKAGE,
237                 /* overrideableByRestore */ true);
238         settingsWriter.persistSyncLocked();
239 
240         SettingsState settingsReader = getSettingStateObject();
241         assertTrue(settingsReader.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
242     }
243 
testResetSetting_preservedFlagIsReset()244     public void testResetSetting_preservedFlagIsReset() {
245         SettingsState settingsState = getSettingStateObject();
246         // Initialize the setting.
247         settingsState.insertSettingLocked(SETTING_NAME, "1", null, false, TEST_PACKAGE);
248         // Update the setting so that preserved flag is set.
249         settingsState.insertSettingLocked(SETTING_NAME, "2", null, false, TEST_PACKAGE);
250 
251         settingsState.resetSettingLocked(SETTING_NAME);
252         assertFalse(settingsState.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
253 
254     }
255 
testModifySettingBySystemPackage_sameValue_preserveFlagNotSet()256     public void testModifySettingBySystemPackage_sameValue_preserveFlagNotSet() {
257         SettingsState settingsState = getSettingStateObject();
258         // Initialize the setting.
259         settingsState.insertSettingLocked(SETTING_NAME, "1", null, false, SYSTEM_PACKAGE);
260         // Update the setting.
261         settingsState.insertSettingLocked(SETTING_NAME, "1", null, false, SYSTEM_PACKAGE);
262 
263         assertFalse(settingsState.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
264     }
265 
testModifySettingBySystemPackage_newValue_preserveFlagSet()266     public void testModifySettingBySystemPackage_newValue_preserveFlagSet() {
267         SettingsState settingsState = getSettingStateObject();
268         // Initialize the setting.
269         settingsState.insertSettingLocked(SETTING_NAME, "1", null, false, SYSTEM_PACKAGE);
270         // Update the setting.
271         settingsState.insertSettingLocked(SETTING_NAME, "2", null, false, SYSTEM_PACKAGE);
272 
273         assertTrue(settingsState.getSettingLocked(SETTING_NAME).isValuePreservedInRestore());
274     }
275 
getSettingStateObject()276     private SettingsState getSettingStateObject() {
277         SettingsState settingsState = new SettingsState(getContext(), mLock, mSettingsFile, 1,
278                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
279         settingsState.setVersionLocked(SettingsState.SETTINGS_VERSION_NEW_ENCODING);
280         return settingsState;
281     }
282 
testInsertSetting_memoryUsage()283     public void testInsertSetting_memoryUsage() {
284         SettingsState settingsState = getSettingStateObject();
285         // No exception should be thrown when there is no cap
286         settingsState.insertSettingLocked(SETTING_NAME, Strings.repeat("A", 20001),
287                 null, false, "p1");
288         settingsState.deleteSettingLocked(SETTING_NAME);
289 
290         settingsState = new SettingsState(getContext(), mLock, mSettingsFile, 1,
291                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper());
292         // System package doesn't have memory usage limit
293         settingsState.insertSettingLocked(SETTING_NAME, Strings.repeat("A", 20001),
294                 null, false, SYSTEM_PACKAGE);
295         settingsState.deleteSettingLocked(SETTING_NAME);
296 
297         // Should not throw if usage is under the cap
298         settingsState.insertSettingLocked(SETTING_NAME, Strings.repeat("A", 19975),
299                 null, false, "p1");
300         settingsState.deleteSettingLocked(SETTING_NAME);
301         try {
302             settingsState.insertSettingLocked(SETTING_NAME, Strings.repeat("A", 20001),
303                     null, false, "p1");
304             fail("Should throw because it exceeded per package memory usage");
305         } catch (IllegalStateException ex) {
306             assertTrue(ex.getMessage().contains("p1"));
307         }
308         try {
309             settingsState.insertSettingLocked(SETTING_NAME, Strings.repeat("A", 20001),
310                     null, false, "p1");
311             fail("Should throw because it exceeded per package memory usage");
312         } catch (IllegalStateException ex) {
313             assertTrue(ex.getMessage().contains("p1"));
314         }
315         assertTrue(settingsState.getSettingLocked(SETTING_NAME).isNull());
316         try {
317             settingsState.insertSettingLocked(Strings.repeat("A", 20001), "",
318                     null, false, "p1");
319             fail("Should throw because it exceeded per package memory usage");
320         } catch (IllegalStateException ex) {
321             assertTrue(ex.getMessage().contains("You are adding too many system settings"));
322         }
323     }
324 
testMemoryUsagePerPackage()325     public void testMemoryUsagePerPackage() {
326         SettingsState settingsState = new SettingsState(getContext(), mLock, mSettingsFile, 1,
327                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper());
328 
329         // Test inserting one key with default
330         final String testKey1 = SETTING_NAME;
331         final String testValue1 = Strings.repeat("A", 100);
332         settingsState.insertSettingLocked(testKey1, testValue1, null, true, TEST_PACKAGE);
333         int expectedMemUsage = (testKey1.length() + testValue1.length()
334                 + testValue1.length() /* size for default */) * Character.BYTES;
335         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
336 
337         // Test inserting another key
338         final String testKey2 = SETTING_NAME + "2";
339         settingsState.insertSettingLocked(testKey2, testValue1, null, false, TEST_PACKAGE);
340         expectedMemUsage += (testKey2.length() + testValue1.length()) * Character.BYTES;
341         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
342 
343         // Test updating first key with new default
344         final String testValue2 = Strings.repeat("A", 300);
345         settingsState.insertSettingLocked(testKey1, testValue2, null, true, TEST_PACKAGE);
346         expectedMemUsage += (testValue2.length() - testValue1.length()) * 2 * Character.BYTES;
347         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
348 
349         // Test updating first key without new default
350         final String testValue3 = Strings.repeat("A", 50);
351         settingsState.insertSettingLocked(testKey1, testValue3, null, false, TEST_PACKAGE);
352         expectedMemUsage -= (testValue2.length() - testValue3.length()) * Character.BYTES;
353         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
354 
355         // Test updating second key
356         settingsState.insertSettingLocked(testKey2, testValue2, null, false, TEST_PACKAGE);
357         expectedMemUsage -= (testValue1.length() - testValue2.length()) * Character.BYTES;
358         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
359 
360         // Test resetting key
361         settingsState.resetSettingLocked(testKey1);
362         expectedMemUsage += (testValue2.length() - testValue3.length()) * Character.BYTES;
363         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
364 
365         // Test resetting default value
366         settingsState.resetSettingDefaultValueLocked(testKey1);
367         expectedMemUsage -= testValue2.length() * Character.BYTES;
368         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
369 
370         // Test deletion
371         settingsState.deleteSettingLocked(testKey2);
372         expectedMemUsage -= (testValue2.length() + testKey2.length() /* key is deleted too */)
373                 * Character.BYTES;
374         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
375 
376         // Test another package with a different key
377         final String testPackage2 = TEST_PACKAGE + "2";
378         final String testKey3 = SETTING_NAME + "3";
379         settingsState.insertSettingLocked(testKey3, testValue1, null, true, testPackage2);
380         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
381         final int expectedMemUsage2 = (testKey3.length() + testValue1.length() * 2)
382                 * Character.BYTES;
383         assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2));
384 
385         // Test system package
386         settingsState.insertSettingLocked(testKey1, testValue1, null, true, SYSTEM_PACKAGE);
387         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
388         assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2));
389         assertEquals(0, settingsState.getMemoryUsage(SYSTEM_PACKAGE));
390 
391         // Test invalid value
392         try {
393             settingsState.insertSettingLocked(testKey1, Strings.repeat("A", 20001), null, false,
394                     TEST_PACKAGE);
395             fail("Should throw because it exceeded per package memory usage");
396         } catch (IllegalStateException ex) {
397             assertTrue(ex.getMessage().contains("You are adding too many system settings"));
398         }
399         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
400 
401         // Test invalid key
402         try {
403             settingsState.insertSettingLocked(Strings.repeat("A", 20001), "", null, false,
404                     TEST_PACKAGE);
405             fail("Should throw because it exceeded per package memory usage");
406         } catch (IllegalStateException ex) {
407             assertTrue(ex.getMessage().contains("You are adding too many system settings"));
408         }
409         assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
410     }
411 
testLargeSettingKey()412     public void testLargeSettingKey() {
413         SettingsState settingsState = new SettingsState(getContext(), mLock, mSettingsFile, 1,
414                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper());
415         final String largeKey = Strings.repeat("A", SettingsState.MAX_LENGTH_PER_STRING + 1);
416         final String testValue = "testValue";
417         synchronized (mLock) {
418             // Test system package
419             try {
420                 settingsState.insertSettingLocked(largeKey, testValue, null, true, SYSTEM_PACKAGE);
421                 fail("Should throw because it exceeded max string length");
422             } catch (IllegalArgumentException ex) {
423                 assertTrue(ex.getMessage().contains("The max length allowed for the string is "));
424             }
425             // Test non system package
426             try {
427                 settingsState.insertSettingLocked(largeKey, testValue, null, true, TEST_PACKAGE);
428                 fail("Should throw because it exceeded max string length");
429             } catch (IllegalArgumentException ex) {
430                 assertTrue(ex.getMessage().contains("The max length allowed for the string is "));
431             }
432         }
433     }
434 
testLargeSettingValue()435     public void testLargeSettingValue() {
436         SettingsState settingsState = new SettingsState(getContext(), mLock, mSettingsFile, 1,
437                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
438         final String testKey = "testKey";
439         final String largeValue = Strings.repeat("A", SettingsState.MAX_LENGTH_PER_STRING + 1);
440         synchronized (mLock) {
441             // Test system package
442             try {
443                 settingsState.insertSettingLocked(testKey, largeValue, null, true, SYSTEM_PACKAGE);
444                 fail("Should throw because it exceeded max string length");
445             } catch (IllegalArgumentException ex) {
446                 assertTrue(ex.getMessage().contains("The max length allowed for the string is "));
447             }
448             // Test non system package
449             try {
450                 settingsState.insertSettingLocked(testKey, largeValue, null, true, TEST_PACKAGE);
451                 fail("Should throw because it exceeded max string length");
452             } catch (IllegalArgumentException ex) {
453                 assertTrue(ex.getMessage().contains("The max length allowed for the string is "));
454             }
455         }
456     }
457 }
458