1 /*
2  * Copyright (C) 2017 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 libcore.util;
18 
19 /**
20  * Utility methods associated with finding updateable time zone data files.
21  */
22 public final class TimeZoneDataFiles {
23 
24     private static final String ANDROID_ROOT_ENV = "ANDROID_ROOT";
25     private static final String ANDROID_DATA_ENV = "ANDROID_DATA";
26 
TimeZoneDataFiles()27     private TimeZoneDataFiles() {}
28 
29     /**
30      * Returns two time zone file paths for the specified file name in an array in the order they
31      * should be tried. See {@link #generateIcuDataPath()} for ICU files instead.
32      * <ul>
33      * <li>[0] - the location of the file in the /data partition (may not exist).</li>
34      * <li>[1] - the location of the file in the /system partition (should exist).</li>
35      * </ul>
36      */
37     // VisibleForTesting
getTimeZoneFilePaths(String fileName)38     public static String[] getTimeZoneFilePaths(String fileName) {
39         return new String[] {
40                 getDataTimeZoneFile(fileName),
41                 getSystemTimeZoneFile(fileName)
42         };
43     }
44 
getDataTimeZoneFile(String fileName)45     private static String getDataTimeZoneFile(String fileName) {
46         return System.getenv(ANDROID_DATA_ENV) + "/misc/zoneinfo/current/" + fileName;
47     }
48 
49     // VisibleForTesting
getSystemTimeZoneFile(String fileName)50     public static String getSystemTimeZoneFile(String fileName) {
51         return System.getenv(ANDROID_ROOT_ENV) + "/usr/share/zoneinfo/" + fileName;
52     }
53 
generateIcuDataPath()54     public static String generateIcuDataPath() {
55         StringBuilder icuDataPathBuilder = new StringBuilder();
56         // ICU should first look in ANDROID_DATA. This is used for (optional) timezone data.
57         String dataIcuDataPath = getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu");
58         if (dataIcuDataPath != null) {
59             icuDataPathBuilder.append(dataIcuDataPath);
60         }
61 
62         // ICU should always look in ANDROID_ROOT.
63         String systemIcuDataPath = getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu");
64         if (systemIcuDataPath != null) {
65             if (icuDataPathBuilder.length() > 0) {
66                 icuDataPathBuilder.append(":");
67             }
68             icuDataPathBuilder.append(systemIcuDataPath);
69         }
70         return icuDataPathBuilder.toString();
71     }
72 
73     /**
74      * Creates a path by combining the value of an environment variable with a relative path.
75      * Returns {@code null} if the environment variable is not set.
76      */
getEnvironmentPath(String environmentVariable, String path)77     private static String getEnvironmentPath(String environmentVariable, String path) {
78         String variable = System.getenv(environmentVariable);
79         if (variable == null) {
80             return null;
81         }
82         return variable + path;
83     }
84 }
85