19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
22269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackborn * Copyright (C) 2010 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
160dc59e78e18493aecd37427531d093e800846c3eBrett Chabotpackage android.util;
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.suitebuilder.annotation.SmallTest;
192269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport android.util.Patterns;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Matcher;
222269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackborn
232269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport junit.framework.TestCase;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
25ded0e6447ed6e0f200dbca13e43c6cf4efc16a1dDan Egnorpublic class PatternsTest extends TestCase {
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testTldPattern() throws Exception {
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean t;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.TOP_LEVEL_DOMAIN.matcher("com").matches();
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Missed valid TLD", t);
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
343ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        // One of the new top level domain.
353ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.TOP_LEVEL_DOMAIN.matcher("me").matches();
363ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertTrue("Missed valid TLD", t);
373ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang
383ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        // One of the new top level test domain.
393ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn--0zwm56d").matches();
403ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertTrue("Missed valid TLD", t);
413ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang
4252fc810f73e0d8e005281e80a981e1ceed855850Shimeng (Simon) Wang        // One of the new top level internationalized domain.
4352fc810f73e0d8e005281e80a981e1ceed855850Shimeng (Simon) Wang        t = Patterns.TOP_LEVEL_DOMAIN.matcher("\uD55C\uAD6D").matches();
4452fc810f73e0d8e005281e80a981e1ceed855850Shimeng (Simon) Wang        assertTrue("Missed valid TLD", t);
4552fc810f73e0d8e005281e80a981e1ceed855850Shimeng (Simon) Wang
463ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.TOP_LEVEL_DOMAIN.matcher("mem").matches();
473ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertFalse("Matched invalid TLD!", t);
483ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang
493ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn").matches();
503ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertFalse("Matched invalid TLD!", t);
513ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang
52494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xer").matches();
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertFalse("Matched invalid TLD!", t);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testUrlPattern() throws Exception {
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean t;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.WEB_URL.matcher("http://www.google.com").matches();
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Valid URL", t);
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
633ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        // Google in one of the new top level domain.
643ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("http://www.google.me").matches();
653ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertTrue("Valid URL", t);
663ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("google.me").matches();
673ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertTrue("Valid URL", t);
683ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang
693ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        // Test url in Chinese: http://xn--fsqu00a.xn--0zwm56d
703ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("http://xn--fsqu00a.xn--0zwm56d").matches();
713ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertTrue("Valid URL", t);
723ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("xn--fsqu00a.xn--0zwm56d").matches();
733ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang        assertTrue("Valid URL", t);
743ed6fbd9e141f20ca382306aa6a355cd544158d1Shimeng (Simon) Wang
75db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        // Url for testing top level Arabic country code domain in Punycode:
76db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        //   http://xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx
77db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("http://xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx").matches();
78db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        assertTrue("Valid URL", t);
79db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx").matches();
80db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        assertTrue("Valid URL", t);
81db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang
8251c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        // Internationalized URL.
8351c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("http://\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
8451c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        assertTrue("Valid URL", t);
8551c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
8651c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        assertTrue("Valid URL", t);
8752fc810f73e0d8e005281e80a981e1ceed855850Shimeng (Simon) Wang        // URL with international TLD.
8852fc810f73e0d8e005281e80a981e1ceed855850Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("\uB3C4\uBA54\uC778.\uD55C\uAD6D").matches();
8952fc810f73e0d8e005281e80a981e1ceed855850Shimeng (Simon) Wang        assertTrue("Valid URL", t);
9051c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang
9140064d3098e17eb447e2b9ee4512b691f6b8c269Shimeng (Simon) Wang        t = Patterns.WEB_URL.matcher("http://brainstormtech.blogs.fortune.cnn.com/2010/03/11/" +
9240064d3098e17eb447e2b9ee4512b691f6b8c269Shimeng (Simon) Wang            "top-five-moments-from-eric-schmidt\u2019s-talk-in-abu-dhabi/").matches();
9340064d3098e17eb447e2b9ee4512b691f6b8c269Shimeng (Simon) Wang        assertTrue("Valid URL", t);
9440064d3098e17eb447e2b9ee4512b691f6b8c269Shimeng (Simon) Wang
95494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.WEB_URL.matcher("ftp://www.example.com").matches();
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertFalse("Matched invalid protocol", t);
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
98494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.WEB_URL.matcher("http://www.example.com:8080").matches();
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Didn't match valid URL with port", t);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
101494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.WEB_URL.matcher("http://www.example.com:8080/?foo=bar").matches();
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Didn't match valid URL with port and query args", t);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
104494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.WEB_URL.matcher("http://www.example.com:8080/~user/?foo=bar").matches();
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Didn't match valid URL with ~", t);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testIpPattern() throws Exception {
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean t;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
112494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.IP_ADDRESS.matcher("172.29.86.3").matches();
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Valid IP", t);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
115494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.IP_ADDRESS.matcher("1234.4321.9.9").matches();
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertFalse("Invalid IP", t);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testDomainPattern() throws Exception {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean t;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
123494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.DOMAIN_NAME.matcher("mail.example.com").matches();
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Valid domain", t);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
126db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        t = Patterns.DOMAIN_NAME.matcher("google.me").matches();
12751c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        assertTrue("Valid domain", t);
12851c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang
12951c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        // Internationalized domains.
13051c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        t = Patterns.DOMAIN_NAME.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
13151c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang        assertTrue("Valid domain", t);
13251c02dbf75fede9b2829af5b821f10e0bc2af124Shimeng (Simon) Wang
133494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.DOMAIN_NAME.matcher("__+&42.xer").matches();
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertFalse("Invalid domain", t);
135db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang
136db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        // Obsolete domain .yu
137db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        t = Patterns.DOMAIN_NAME.matcher("test.yu").matches();
138db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        assertFalse("Obsolete country code top level domain", t);
139db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang
140db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        // Testing top level Arabic country code domain in Punycode:
141db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        t = Patterns.DOMAIN_NAME.matcher("xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c").matches();
142db990751ef8e535ea5cb3d527e36936e119095e8Shimeng (Simon) Wang        assertTrue("Valid domain", t);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testPhonePattern() throws Exception {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean t;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
149494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.PHONE.matcher("(919) 555-1212").matches();
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertTrue("Valid phone", t);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
152494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor        t = Patterns.PHONE.matcher("2334 9323/54321").matches();
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertFalse("Invalid phone", t);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String[] tests = {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 16505551212 this\n",
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 6505551212 this\n",
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 5551212 this\n",
159a37fc575a4ac40f3ff2e9a9f2108b577a649db73Bin Zhu                "Me: 2211 this\n",
160a37fc575a4ac40f3ff2e9a9f2108b577a649db73Bin Zhu                "Me: 112 this\n",
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 1-650-555-1212 this\n",
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: (650) 555-1212 this\n",
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: +1 (650) 555-1212 this\n",
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: +1-650-555-1212 this\n",
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 650-555-1212 this\n",
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 555-1212 this\n",
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 1.650.555.1212 this\n",
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: (650) 555.1212 this\n",
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: +1 (650) 555.1212 this\n",
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: +1.650.555.1212 this\n",
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 650.555.1212 this\n",
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 555.1212 this\n",
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 1 650 555 1212 this\n",
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: (650) 555 1212 this\n",
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: +1 (650) 555 1212 this\n",
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: +1 650 555 1212 this\n",
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 650 555 1212 this\n",
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Me: 555 1212 this\n",
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (String test : tests) {
185494a1dc5e95e22839b06bf7de84426094a38691aDan Egnor            Matcher m = Patterns.PHONE.matcher(test);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            assertTrue("Valid phone " + test, m.find());
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
191