• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.timezone;
18 
19 import java.util.ArrayList;
20 import java.util.List;
21 
22 /**
23  * Utility methods associated with finding updateable time zone data files.
24  *
25  * @hide
26  */
27 @libcore.api.CorePlatformApi
28 public final class TimeZoneDataFiles {
29     private static final String ANDROID_ROOT_ENV = "ANDROID_ROOT";
30     private static final String ANDROID_RUNTIME_ROOT_ENV = "ANDROID_RUNTIME_ROOT";
31     private static final String ANDROID_TZDATA_ROOT_ENV = "ANDROID_TZDATA_ROOT";
32     private static final String ANDROID_DATA_ENV = "ANDROID_DATA";
33 
TimeZoneDataFiles()34     private TimeZoneDataFiles() {}
35 
36     /**
37      * Returns time zone file paths for the specified file name in an array in the order they
38      * should be tried. See {@link #generateIcuDataPath()} for ICU files instead.
39      * <ul>
40      * <li>[0] - the location of the file in the /data partition (may not exist).</li>
41      * <li>[1] - the location of the file from the time zone module under /apex (may not exist).
42      * </li>
43      * <li>[2] - the location of the file from the runtime module under /apex (should exist).</li>
44      * </ul>
45      * <li>[3] - the location of the file in the /system partition (should exist).</li>
46      */
47     // VisibleForTesting
getTimeZoneFilePaths(String fileName)48     public static String[] getTimeZoneFilePaths(String fileName) {
49         return new String[] {
50                 getDataTimeZoneFile(fileName),
51                 getTimeZoneModuleFile("tz/" + fileName),
52                 getRuntimeModuleFile("tz/" + fileName),
53                 getSystemTimeZoneFile(fileName)
54         };
55     }
56 
57     // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
58     @libcore.api.CorePlatformApi
getDataTimeZoneRootDir()59     public static String getDataTimeZoneRootDir() {
60         return System.getenv(ANDROID_DATA_ENV) + "/misc/zoneinfo/";
61     }
62 
63     @libcore.api.CorePlatformApi
getDataTimeZoneFile(String fileName)64     public static String getDataTimeZoneFile(String fileName) {
65         return getDataTimeZoneRootDir() + "current/" + fileName;
66     }
67 
getTimeZoneModuleFile(String fileName)68     public static String getTimeZoneModuleFile(String fileName) {
69         return System.getenv(ANDROID_TZDATA_ROOT_ENV) + "/etc/" + fileName;
70     }
71 
72     // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
73     @libcore.api.CorePlatformApi
getRuntimeModuleTzVersionFile()74     public static String getRuntimeModuleTzVersionFile() {
75         return getRuntimeModuleFile("tz/" + TzDataSetVersion.DEFAULT_FILE_NAME);
76     }
77 
getRuntimeModuleFile(String fileName)78     public static String getRuntimeModuleFile(String fileName) {
79         return System.getenv(ANDROID_RUNTIME_ROOT_ENV) + "/etc/" + fileName;
80     }
81 
getSystemTimeZoneFile(String fileName)82     public static String getSystemTimeZoneFile(String fileName) {
83         return getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/share/zoneinfo/" + fileName);
84     }
85 
getSystemIcuFile(String fileName)86     public static String getSystemIcuFile(String fileName) {
87         return getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu/" + fileName);
88     }
89 
generateIcuDataPath()90     public static String generateIcuDataPath() {
91         List<String> paths = new ArrayList<>(3);
92 
93         // ICU should first look in ANDROID_DATA. This is used for (optional) time zone data
94         // delivered by APK (https://source.android.com/devices/tech/config/timezone-rules)
95         String dataIcuDataPath =
96                 getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu/");
97         if (dataIcuDataPath != null) {
98             paths.add(dataIcuDataPath);
99         }
100 
101         // ICU should then look for a mounted time zone module file in /apex. This is used for
102         // (optional) time zone data that can be updated with an APEX file.
103         String timeZoneModuleIcuDataPath = getTimeZoneModuleFile("icu/");
104         if (timeZoneModuleIcuDataPath != null) {
105             paths.add(timeZoneModuleIcuDataPath);
106         }
107 
108         // ICU should always look in the runtime module path as this is where most of the data
109         // can be found.
110         String runtimeModuleIcuDataPath = getRuntimeModuleFile("icu/");
111         if (runtimeModuleIcuDataPath != null) {
112             paths.add(runtimeModuleIcuDataPath);
113         }
114         return String.join(":", paths);
115     }
116 
117     /**
118      * Creates a path by combining the value of an environment variable with a relative path.
119      * Returns {@code null} if the environment variable is not set.
120      */
getEnvironmentPath(String environmentVariable, String path)121     private static String getEnvironmentPath(String environmentVariable, String path) {
122         String variable = System.getenv(environmentVariable);
123         if (variable == null) {
124             return null;
125         }
126         return variable + path;
127     }
128 }
129