Move ZoneGetter into SettingsLib

Change-Id: I8ecfc018e6de2514e9ada4c1b6fe9c8d71cc4e88
diff --git a/packages/SettingsLib/res/xml/timezones.xml b/packages/SettingsLib/res/xml/timezones.xml
new file mode 100644
index 0000000..4426495
--- /dev/null
+++ b/packages/SettingsLib/res/xml/timezones.xml
@@ -0,0 +1,91 @@
+<timezones>
+    <timezone id="Pacific/Midway"></timezone>
+    <timezone id="Pacific/Honolulu"></timezone>
+    <timezone id="America/Anchorage"></timezone>
+    <timezone id="America/Los_Angeles"></timezone>
+    <timezone id="America/Tijuana"></timezone>
+    <timezone id="America/Phoenix"></timezone>
+    <timezone id="America/Chihuahua"></timezone>
+    <timezone id="America/Denver"></timezone>
+    <timezone id="America/Costa_Rica"></timezone>
+    <timezone id="America/Chicago"></timezone>
+    <timezone id="America/Mexico_City"></timezone>
+    <timezone id="America/Regina"></timezone>
+    <timezone id="America/Bogota"></timezone>
+    <timezone id="America/New_York"></timezone>
+    <timezone id="America/Caracas"></timezone>
+    <timezone id="America/Barbados"></timezone>
+    <timezone id="America/Halifax"></timezone>
+    <timezone id="America/Manaus"></timezone>
+    <timezone id="America/Santiago"></timezone>
+    <timezone id="America/St_Johns"></timezone>
+    <timezone id="America/Recife"></timezone>
+    <timezone id="America/Sao_Paulo"></timezone>
+    <timezone id="America/Buenos_Aires"></timezone>
+    <timezone id="America/Godthab"></timezone>
+    <timezone id="America/Montevideo"></timezone>
+    <timezone id="Atlantic/South_Georgia"></timezone>
+    <timezone id="Atlantic/Azores"></timezone>
+    <timezone id="Atlantic/Cape_Verde"></timezone>
+    <timezone id="Africa/Casablanca"></timezone>
+    <timezone id="Europe/London"></timezone>
+    <timezone id="Europe/Amsterdam"></timezone>
+    <timezone id="Europe/Belgrade"></timezone>
+    <timezone id="Europe/Brussels"></timezone>
+    <timezone id="Europe/Madrid"></timezone>
+    <timezone id="Europe/Sarajevo"></timezone>
+    <timezone id="Africa/Windhoek"></timezone>
+    <timezone id="Africa/Brazzaville"></timezone>
+    <timezone id="Asia/Amman"></timezone>
+    <timezone id="Europe/Athens"></timezone>
+    <timezone id="Europe/Istanbul"></timezone>
+    <timezone id="Asia/Beirut"></timezone>
+    <timezone id="Africa/Cairo"></timezone>
+    <timezone id="Europe/Helsinki"></timezone>
+    <timezone id="Asia/Jerusalem"></timezone>
+    <timezone id="Europe/Minsk"></timezone>
+    <timezone id="Africa/Harare"></timezone>
+    <timezone id="Asia/Baghdad"></timezone>
+    <timezone id="Europe/Moscow"></timezone>
+    <timezone id="Asia/Kuwait"></timezone>
+    <timezone id="Africa/Nairobi"></timezone>
+    <timezone id="Asia/Tehran"></timezone>
+    <timezone id="Asia/Baku"></timezone>
+    <timezone id="Asia/Tbilisi"></timezone>
+    <timezone id="Asia/Yerevan"></timezone>
+    <timezone id="Asia/Dubai"></timezone>
+    <timezone id="Asia/Kabul"></timezone>
+    <timezone id="Asia/Karachi"></timezone>
+    <timezone id="Asia/Oral"></timezone>
+    <timezone id="Asia/Yekaterinburg"></timezone>
+    <timezone id="Asia/Calcutta"></timezone>
+    <timezone id="Asia/Colombo"></timezone>
+    <timezone id="Asia/Katmandu"></timezone>
+    <timezone id="Asia/Almaty"></timezone>
+    <timezone id="Asia/Rangoon"></timezone>
+    <timezone id="Asia/Krasnoyarsk"></timezone>
+    <timezone id="Asia/Bangkok"></timezone>
+    <timezone id="Asia/Jakarta"></timezone>
+    <timezone id="Asia/Shanghai"></timezone>
+    <timezone id="Asia/Hong_Kong"></timezone>
+    <timezone id="Asia/Irkutsk"></timezone>
+    <timezone id="Asia/Kuala_Lumpur"></timezone>
+    <timezone id="Australia/Perth"></timezone>
+    <timezone id="Asia/Taipei"></timezone>
+    <timezone id="Asia/Seoul"></timezone>
+    <timezone id="Asia/Tokyo"></timezone>
+    <timezone id="Asia/Yakutsk"></timezone>
+    <timezone id="Australia/Adelaide"></timezone>
+    <timezone id="Australia/Darwin"></timezone>
+    <timezone id="Australia/Brisbane"></timezone>
+    <timezone id="Australia/Hobart"></timezone>
+    <timezone id="Australia/Sydney"></timezone>
+    <timezone id="Asia/Vladivostok"></timezone>
+    <timezone id="Pacific/Guam"></timezone>
+    <timezone id="Asia/Magadan"></timezone>
+    <timezone id="Pacific/Noumea"></timezone>
+    <timezone id="Pacific/Majuro"></timezone>
+    <timezone id="Pacific/Auckland"></timezone>
+    <timezone id="Pacific/Fiji"></timezone>
+    <timezone id="Pacific/Tongatapu"></timezone>
+</timezones>
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
new file mode 100644
index 0000000..12ead4e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settingslib.datetime;
+
+import android.content.Context;
+import android.content.res.XmlResourceParser;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import com.android.settingslib.R;
+
+import libcore.icu.TimeZoneNames;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class ZoneGetter {
+    private static final String TAG = "ZoneGetter";
+
+    private static final String XMLTAG_TIMEZONE = "timezone";
+
+    public static final String KEY_ID = "id";  // value: String
+    public static final String KEY_DISPLAYNAME = "name";  // value: String
+    public static final String KEY_GMT = "gmt";  // value: String
+    public static final String KEY_OFFSET = "offset";  // value: int (Integer)
+
+    private final List<HashMap<String, Object>> mZones = new ArrayList<>();
+    private final HashSet<String> mLocalZones = new HashSet<>();
+    private final Date mNow = Calendar.getInstance().getTime();
+    private final SimpleDateFormat mZoneNameFormatter = new SimpleDateFormat("zzzz");
+
+    public List<HashMap<String, Object>> getZones(Context context) {
+        for (String olsonId : TimeZoneNames.forLocale(Locale.getDefault())) {
+            mLocalZones.add(olsonId);
+        }
+        try {
+            XmlResourceParser xrp = context.getResources().getXml(R.xml.timezones);
+            while (xrp.next() != XmlResourceParser.START_TAG) {
+                continue;
+            }
+            xrp.next();
+            while (xrp.getEventType() != XmlResourceParser.END_TAG) {
+                while (xrp.getEventType() != XmlResourceParser.START_TAG) {
+                    if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
+                        return mZones;
+                    }
+                    xrp.next();
+                }
+                if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
+                    String olsonId = xrp.getAttributeValue(0);
+                    addTimeZone(olsonId);
+                }
+                while (xrp.getEventType() != XmlResourceParser.END_TAG) {
+                    xrp.next();
+                }
+                xrp.next();
+            }
+            xrp.close();
+        } catch (XmlPullParserException xppe) {
+            Log.e(TAG, "Ill-formatted timezones.xml file");
+        } catch (java.io.IOException ioe) {
+            Log.e(TAG, "Unable to read timezones.xml file");
+        }
+        return mZones;
+    }
+
+    private void addTimeZone(String olsonId) {
+        // We always need the "GMT-07:00" string.
+        final TimeZone tz = TimeZone.getTimeZone(olsonId);
+
+        // For the display name, we treat time zones within the country differently
+        // from other countries' time zones. So in en_US you'd get "Pacific Daylight Time"
+        // but in de_DE you'd get "Los Angeles" for the same time zone.
+        String displayName;
+        if (mLocalZones.contains(olsonId)) {
+            // Within a country, we just use the local name for the time zone.
+            mZoneNameFormatter.setTimeZone(tz);
+            displayName = mZoneNameFormatter.format(mNow);
+        } else {
+            // For other countries' time zones, we use the exemplar location.
+            final String localeName = Locale.getDefault().toString();
+            displayName = TimeZoneNames.getExemplarLocation(localeName, olsonId);
+        }
+
+        final HashMap<String, Object> map = new HashMap<>();
+        map.put(KEY_ID, olsonId);
+        map.put(KEY_DISPLAYNAME, displayName);
+        map.put(KEY_GMT, getTimeZoneText(tz, false));
+        map.put(KEY_OFFSET, tz.getOffset(mNow.getTime()));
+
+        mZones.add(map);
+    }
+
+    public static String getTimeZoneText(TimeZone tz, boolean includeName) {
+        Date now = new Date();
+
+        // Use SimpleDateFormat to format the GMT+00:00 string.
+        SimpleDateFormat gmtFormatter = new SimpleDateFormat("ZZZZ");
+        gmtFormatter.setTimeZone(tz);
+        String gmtString = gmtFormatter.format(now);
+
+        // Ensure that the "GMT+" stays with the "00:00" even if the digits are RTL.
+        BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+        Locale l = Locale.getDefault();
+        boolean isRtl = TextUtils.getLayoutDirectionFromLocale(l) == View.LAYOUT_DIRECTION_RTL;
+        gmtString = bidiFormatter.unicodeWrap(gmtString,
+                isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR);
+
+        if (!includeName) {
+            return gmtString;
+        }
+
+        // Optionally append the time zone name.
+        SimpleDateFormat zoneNameFormatter = new SimpleDateFormat("zzzz");
+        zoneNameFormatter.setTimeZone(tz);
+        String zoneNameString = zoneNameFormatter.format(now);
+
+        // We don't use punctuation here to avoid having to worry about localizing that too!
+        return gmtString + " " + zoneNameString;
+    }
+}