Loading packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java +121 −84 Original line number Diff line number Diff line Loading @@ -40,23 +40,47 @@ import java.util.Map; import java.util.Set; import java.util.TimeZone; /** * ZoneGetter is the utility class to get time zone and zone list, and both of them have display * name in time zone. In this class, we will keep consistency about display names for all * the methods. * * The display name chosen for each zone entry depends on whether the zone is one associated * with the country of the user's chosen locale. For "local" zones we prefer the "long name" * (e.g. "Europe/London" -> "British Summer Time" for people in the UK). For "non-local" * zones we prefer the exemplar location (e.g. "Europe/London" -> "London" for English * speakers from outside the UK). This heuristic is based on the fact that people are * typically familiar with their local timezones and exemplar locations don't always match * modern-day expectations for people living in the country covered. Large countries like * China that mostly use a single timezone (olson id: "Asia/Shanghai") may not live near * "Shanghai" and prefer the long name over the exemplar location. The only time we don't * follow this policy for local zones is when Android supplies multiple olson IDs to choose * from and the use of a zone's long name leads to ambiguity. For example, at the time of * writing Android lists 5 olson ids for Australia which collapse to 2 different zone names * in winter but 4 different zone names in summer. The ambiguity leads to the users * selecting the wrong olson ids. * */ 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 ZoneGetter() {} private static final String XMLTAG_TIMEZONE = "timezone"; public static String getTimeZoneOffsetAndName(TimeZone tz, Date now) { Locale locale = Locale.getDefault(); String gmtString = getGmtOffsetString(locale, tz, now); TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale); String zoneNameString = getZoneLongName(timeZoneNames, tz, now); public static String getTimeZoneOffsetAndName(Context context, TimeZone tz, Date now) { final Locale locale = Locale.getDefault(); final String gmtString = getGmtOffsetString(locale, tz, now); final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale); final ZoneGetterData data = new ZoneGetterData(context); final boolean useExemplarLocationForLocalNames = shouldUseExemplarLocationForLocalNames(data, timeZoneNames); final String zoneNameString = getTimeZoneDisplayName(data, timeZoneNames, useExemplarLocationForLocalNames, tz, tz.getID()); if (zoneNameString == null) { return gmtString; } Loading @@ -69,82 +93,20 @@ public class ZoneGetter { final Locale locale = Locale.getDefault(); final Date now = new Date(); final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale); // The display name chosen for each zone entry depends on whether the zone is one associated // with the country of the user's chosen locale. For "local" zones we prefer the "long name" // (e.g. "Europe/London" -> "British Summer Time" for people in the UK). For "non-local" // zones we prefer the exemplar location (e.g. "Europe/London" -> "London" for English // speakers from outside the UK). This heuristic is based on the fact that people are // typically familiar with their local timezones and exemplar locations don't always match // modern-day expectations for people living in the country covered. Large countries like // China that mostly use a single timezone (olson id: "Asia/Shanghai") may not live near // "Shanghai" and prefer the long name over the exemplar location. The only time we don't // follow this policy for local zones is when Android supplies multiple olson IDs to choose // from and the use of a zone's long name leads to ambiguity. For example, at the time of // writing Android lists 5 olson ids for Australia which collapse to 2 different zone names // in winter but 4 different zone names in summer. The ambiguity leads to the users // selecting the wrong olson ids. // Get the list of olson ids to display to the user. List<String> olsonIdsToDisplayList = readTimezonesToDisplay(context); // Store the information we are going to need more than once. final int zoneCount = olsonIdsToDisplayList.size(); final String[] olsonIdsToDisplay = new String[zoneCount]; final TimeZone[] timeZones = new TimeZone[zoneCount]; final String[] gmtOffsetStrings = new String[zoneCount]; for (int i = 0; i < zoneCount; i++) { String olsonId = olsonIdsToDisplayList.get(i); olsonIdsToDisplay[i] = olsonId; TimeZone tz = TimeZone.getTimeZone(olsonId); timeZones[i] = tz; gmtOffsetStrings[i] = getGmtOffsetString(locale, tz, now); } // Create a lookup of local zone IDs. Set<String> localZoneIds = new HashSet<String>(); for (String olsonId : libcore.icu.TimeZoneNames.forLocale(locale)) { localZoneIds.add(olsonId); } final ZoneGetterData data = new ZoneGetterData(context); // Work out whether the display names we would show by default would be ambiguous. Set<String> localZoneNames = new HashSet<String>(); boolean useExemplarLocationForLocalNames = false; for (int i = 0; i < zoneCount; i++) { String olsonId = olsonIdsToDisplay[i]; if (localZoneIds.contains(olsonId)) { TimeZone tz = timeZones[i]; String displayName = getZoneLongName(timeZoneNames, tz, now); if (displayName == null) { displayName = gmtOffsetStrings[i]; } boolean nameIsUnique = localZoneNames.add(displayName); if (!nameIsUnique) { useExemplarLocationForLocalNames = true; break; } } } final boolean useExemplarLocationForLocalNames = shouldUseExemplarLocationForLocalNames(data, timeZoneNames); // Generate the list of zone entries to return. List<Map<String, Object>> zones = new ArrayList<Map<String, Object>>(); for (int i = 0; i < zoneCount; i++) { String olsonId = olsonIdsToDisplay[i]; TimeZone tz = timeZones[i]; String gmtOffsetString = gmtOffsetStrings[i]; for (int i = 0; i < data.zoneCount; i++) { TimeZone tz = data.timeZones[i]; String gmtOffsetString = data.gmtOffsetStrings[i]; boolean isLocalZoneId = localZoneIds.contains(olsonId); boolean preferLongName = isLocalZoneId && !useExemplarLocationForLocalNames; String displayName; if (preferLongName) { displayName = getZoneLongName(timeZoneNames, tz, now); } else { displayName = timeZoneNames.getExemplarLocationName(tz.getID()); if (displayName == null || displayName.isEmpty()) { // getZoneExemplarLocation can return null. Fall back to the long name. displayName = getZoneLongName(timeZoneNames, tz, now); } } String displayName = getTimeZoneDisplayName(data, timeZoneNames, useExemplarLocationForLocalNames, tz, data.olsonIdsToDisplay[i]); if (displayName == null || displayName.isEmpty()) { displayName = gmtOffsetString; } Loading Loading @@ -198,12 +160,54 @@ public class ZoneGetter { return olsonIds; } private static boolean shouldUseExemplarLocationForLocalNames(ZoneGetterData data, TimeZoneNames timeZoneNames) { final Set<String> localZoneNames = new HashSet<String>(); final Date now = new Date(); for (int i = 0; i < data.zoneCount; i++) { final String olsonId = data.olsonIdsToDisplay[i]; if (data.localZoneIds.contains(olsonId)) { final TimeZone tz = data.timeZones[i]; String displayName = getZoneLongName(timeZoneNames, tz, now); if (displayName == null) { displayName = data.gmtOffsetStrings[i]; } final boolean nameIsUnique = localZoneNames.add(displayName); if (!nameIsUnique) { return true; } } } return false; } private static String getTimeZoneDisplayName(ZoneGetterData data, TimeZoneNames timeZoneNames, boolean useExemplarLocationForLocalNames, TimeZone tz, String olsonId) { final Date now = new Date(); final boolean isLocalZoneId = data.localZoneIds.contains(olsonId); final boolean preferLongName = isLocalZoneId && !useExemplarLocationForLocalNames; String displayName; if (preferLongName) { displayName = getZoneLongName(timeZoneNames, tz, now); } else { displayName = timeZoneNames.getExemplarLocationName(tz.getID()); if (displayName == null || displayName.isEmpty()) { // getZoneExemplarLocation can return null. Fall back to the long name. displayName = getZoneLongName(timeZoneNames, tz, now); } } return displayName; } /** * Returns the long name for the timezone for the given locale at the time specified. * Can return {@code null}. */ private static String getZoneLongName(TimeZoneNames names, TimeZone tz, Date now) { TimeZoneNames.NameType nameType = final TimeZoneNames.NameType nameType = tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT : TimeZoneNames.NameType.LONG_STANDARD; return names.getDisplayName(tz.getID(), nameType, now.getTime()); Loading @@ -211,15 +215,48 @@ public class ZoneGetter { private static String getGmtOffsetString(Locale locale, TimeZone tz, Date now) { // Use SimpleDateFormat to format the GMT+00:00 string. SimpleDateFormat gmtFormatter = new SimpleDateFormat("ZZZZ"); final 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(); final BidiFormatter bidiFormatter = BidiFormatter.getInstance(); boolean isRtl = TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL; gmtString = bidiFormatter.unicodeWrap(gmtString, isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR); return gmtString; } private static final class ZoneGetterData { public final String[] olsonIdsToDisplay; public final String[] gmtOffsetStrings; public final TimeZone[] timeZones; public final Set<String> localZoneIds; public final int zoneCount; public ZoneGetterData(Context context) { final Locale locale = Locale.getDefault(); final Date now = new Date(); final List<String> olsonIdsToDisplayList = readTimezonesToDisplay(context); // Load all the data needed to display time zones zoneCount = olsonIdsToDisplayList.size(); olsonIdsToDisplay = new String[zoneCount]; timeZones = new TimeZone[zoneCount]; gmtOffsetStrings = new String[zoneCount]; for (int i = 0; i < zoneCount; i++) { final String olsonId = olsonIdsToDisplayList.get(i); olsonIdsToDisplay[i] = olsonId; final TimeZone tz = TimeZone.getTimeZone(olsonId); timeZones[i] = tz; gmtOffsetStrings[i] = getGmtOffsetString(locale, tz, now); } // Create a lookup of local zone IDs. localZoneIds = new HashSet<String>(); for (String olsonId : libcore.icu.TimeZoneNames.forLocale(locale)) { localZoneIds.add(olsonId); } } } } No newline at end of file packages/SettingsLib/tests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/> <uses-permission android:name="android.permission.SET_TIME_ZONE" /> <application> <uses-library android:name="android.test.runner" /> Loading packages/SettingsLib/tests/src/com/android/settingslib/utils/ZoneGetterTest.java 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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.utils; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.support.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.*; import com.android.settingslib.datetime.ZoneGetter; import static junit.framework.Assert.assertTrue; @RunWith(AndroidJUnit4.class) @SmallTest public class ZoneGetterTest { private static final String TIME_ZONE_LONDON_ID = "Europe/London"; private static final String TIME_ZONE_LA_ID = "America/Los_Angeles"; private Locale mLocaleEnUs; private Calendar mCalendar; @Before public void setUp() { mLocaleEnUs = new Locale("en", "us"); Locale.setDefault(mLocaleEnUs); mCalendar = new GregorianCalendar(2016, 9, 1); } @Test public void getTimeZoneOffsetAndName_setLondon_returnLondon() { // Check it will ends with 'London', not 'British Summer Time' or sth else testTimeZoneOffsetAndNameInner(TIME_ZONE_LONDON_ID, "London"); } @Test public void getTimeZoneOffsetAndName_setLosAngeles_returnPacificDaylightTime() { // Check it will ends with 'Pacific Daylight Time', not 'Los_Angeles' testTimeZoneOffsetAndNameInner(TIME_ZONE_LA_ID, "Pacific Daylight Time"); } private void testTimeZoneOffsetAndNameInner(String timeZoneId, String expectedName) { final Context context = InstrumentationRegistry.getContext(); final TimeZone timeZone = TimeZone.getTimeZone(timeZoneId); String timeZoneString = ZoneGetter.getTimeZoneOffsetAndName(context, timeZone, mCalendar.getTime()); assertTrue(timeZoneString.endsWith(expectedName)); } } Loading
packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java +121 −84 Original line number Diff line number Diff line Loading @@ -40,23 +40,47 @@ import java.util.Map; import java.util.Set; import java.util.TimeZone; /** * ZoneGetter is the utility class to get time zone and zone list, and both of them have display * name in time zone. In this class, we will keep consistency about display names for all * the methods. * * The display name chosen for each zone entry depends on whether the zone is one associated * with the country of the user's chosen locale. For "local" zones we prefer the "long name" * (e.g. "Europe/London" -> "British Summer Time" for people in the UK). For "non-local" * zones we prefer the exemplar location (e.g. "Europe/London" -> "London" for English * speakers from outside the UK). This heuristic is based on the fact that people are * typically familiar with their local timezones and exemplar locations don't always match * modern-day expectations for people living in the country covered. Large countries like * China that mostly use a single timezone (olson id: "Asia/Shanghai") may not live near * "Shanghai" and prefer the long name over the exemplar location. The only time we don't * follow this policy for local zones is when Android supplies multiple olson IDs to choose * from and the use of a zone's long name leads to ambiguity. For example, at the time of * writing Android lists 5 olson ids for Australia which collapse to 2 different zone names * in winter but 4 different zone names in summer. The ambiguity leads to the users * selecting the wrong olson ids. * */ 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 ZoneGetter() {} private static final String XMLTAG_TIMEZONE = "timezone"; public static String getTimeZoneOffsetAndName(TimeZone tz, Date now) { Locale locale = Locale.getDefault(); String gmtString = getGmtOffsetString(locale, tz, now); TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale); String zoneNameString = getZoneLongName(timeZoneNames, tz, now); public static String getTimeZoneOffsetAndName(Context context, TimeZone tz, Date now) { final Locale locale = Locale.getDefault(); final String gmtString = getGmtOffsetString(locale, tz, now); final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale); final ZoneGetterData data = new ZoneGetterData(context); final boolean useExemplarLocationForLocalNames = shouldUseExemplarLocationForLocalNames(data, timeZoneNames); final String zoneNameString = getTimeZoneDisplayName(data, timeZoneNames, useExemplarLocationForLocalNames, tz, tz.getID()); if (zoneNameString == null) { return gmtString; } Loading @@ -69,82 +93,20 @@ public class ZoneGetter { final Locale locale = Locale.getDefault(); final Date now = new Date(); final TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale); // The display name chosen for each zone entry depends on whether the zone is one associated // with the country of the user's chosen locale. For "local" zones we prefer the "long name" // (e.g. "Europe/London" -> "British Summer Time" for people in the UK). For "non-local" // zones we prefer the exemplar location (e.g. "Europe/London" -> "London" for English // speakers from outside the UK). This heuristic is based on the fact that people are // typically familiar with their local timezones and exemplar locations don't always match // modern-day expectations for people living in the country covered. Large countries like // China that mostly use a single timezone (olson id: "Asia/Shanghai") may not live near // "Shanghai" and prefer the long name over the exemplar location. The only time we don't // follow this policy for local zones is when Android supplies multiple olson IDs to choose // from and the use of a zone's long name leads to ambiguity. For example, at the time of // writing Android lists 5 olson ids for Australia which collapse to 2 different zone names // in winter but 4 different zone names in summer. The ambiguity leads to the users // selecting the wrong olson ids. // Get the list of olson ids to display to the user. List<String> olsonIdsToDisplayList = readTimezonesToDisplay(context); // Store the information we are going to need more than once. final int zoneCount = olsonIdsToDisplayList.size(); final String[] olsonIdsToDisplay = new String[zoneCount]; final TimeZone[] timeZones = new TimeZone[zoneCount]; final String[] gmtOffsetStrings = new String[zoneCount]; for (int i = 0; i < zoneCount; i++) { String olsonId = olsonIdsToDisplayList.get(i); olsonIdsToDisplay[i] = olsonId; TimeZone tz = TimeZone.getTimeZone(olsonId); timeZones[i] = tz; gmtOffsetStrings[i] = getGmtOffsetString(locale, tz, now); } // Create a lookup of local zone IDs. Set<String> localZoneIds = new HashSet<String>(); for (String olsonId : libcore.icu.TimeZoneNames.forLocale(locale)) { localZoneIds.add(olsonId); } final ZoneGetterData data = new ZoneGetterData(context); // Work out whether the display names we would show by default would be ambiguous. Set<String> localZoneNames = new HashSet<String>(); boolean useExemplarLocationForLocalNames = false; for (int i = 0; i < zoneCount; i++) { String olsonId = olsonIdsToDisplay[i]; if (localZoneIds.contains(olsonId)) { TimeZone tz = timeZones[i]; String displayName = getZoneLongName(timeZoneNames, tz, now); if (displayName == null) { displayName = gmtOffsetStrings[i]; } boolean nameIsUnique = localZoneNames.add(displayName); if (!nameIsUnique) { useExemplarLocationForLocalNames = true; break; } } } final boolean useExemplarLocationForLocalNames = shouldUseExemplarLocationForLocalNames(data, timeZoneNames); // Generate the list of zone entries to return. List<Map<String, Object>> zones = new ArrayList<Map<String, Object>>(); for (int i = 0; i < zoneCount; i++) { String olsonId = olsonIdsToDisplay[i]; TimeZone tz = timeZones[i]; String gmtOffsetString = gmtOffsetStrings[i]; for (int i = 0; i < data.zoneCount; i++) { TimeZone tz = data.timeZones[i]; String gmtOffsetString = data.gmtOffsetStrings[i]; boolean isLocalZoneId = localZoneIds.contains(olsonId); boolean preferLongName = isLocalZoneId && !useExemplarLocationForLocalNames; String displayName; if (preferLongName) { displayName = getZoneLongName(timeZoneNames, tz, now); } else { displayName = timeZoneNames.getExemplarLocationName(tz.getID()); if (displayName == null || displayName.isEmpty()) { // getZoneExemplarLocation can return null. Fall back to the long name. displayName = getZoneLongName(timeZoneNames, tz, now); } } String displayName = getTimeZoneDisplayName(data, timeZoneNames, useExemplarLocationForLocalNames, tz, data.olsonIdsToDisplay[i]); if (displayName == null || displayName.isEmpty()) { displayName = gmtOffsetString; } Loading Loading @@ -198,12 +160,54 @@ public class ZoneGetter { return olsonIds; } private static boolean shouldUseExemplarLocationForLocalNames(ZoneGetterData data, TimeZoneNames timeZoneNames) { final Set<String> localZoneNames = new HashSet<String>(); final Date now = new Date(); for (int i = 0; i < data.zoneCount; i++) { final String olsonId = data.olsonIdsToDisplay[i]; if (data.localZoneIds.contains(olsonId)) { final TimeZone tz = data.timeZones[i]; String displayName = getZoneLongName(timeZoneNames, tz, now); if (displayName == null) { displayName = data.gmtOffsetStrings[i]; } final boolean nameIsUnique = localZoneNames.add(displayName); if (!nameIsUnique) { return true; } } } return false; } private static String getTimeZoneDisplayName(ZoneGetterData data, TimeZoneNames timeZoneNames, boolean useExemplarLocationForLocalNames, TimeZone tz, String olsonId) { final Date now = new Date(); final boolean isLocalZoneId = data.localZoneIds.contains(olsonId); final boolean preferLongName = isLocalZoneId && !useExemplarLocationForLocalNames; String displayName; if (preferLongName) { displayName = getZoneLongName(timeZoneNames, tz, now); } else { displayName = timeZoneNames.getExemplarLocationName(tz.getID()); if (displayName == null || displayName.isEmpty()) { // getZoneExemplarLocation can return null. Fall back to the long name. displayName = getZoneLongName(timeZoneNames, tz, now); } } return displayName; } /** * Returns the long name for the timezone for the given locale at the time specified. * Can return {@code null}. */ private static String getZoneLongName(TimeZoneNames names, TimeZone tz, Date now) { TimeZoneNames.NameType nameType = final TimeZoneNames.NameType nameType = tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT : TimeZoneNames.NameType.LONG_STANDARD; return names.getDisplayName(tz.getID(), nameType, now.getTime()); Loading @@ -211,15 +215,48 @@ public class ZoneGetter { private static String getGmtOffsetString(Locale locale, TimeZone tz, Date now) { // Use SimpleDateFormat to format the GMT+00:00 string. SimpleDateFormat gmtFormatter = new SimpleDateFormat("ZZZZ"); final 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(); final BidiFormatter bidiFormatter = BidiFormatter.getInstance(); boolean isRtl = TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL; gmtString = bidiFormatter.unicodeWrap(gmtString, isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR); return gmtString; } private static final class ZoneGetterData { public final String[] olsonIdsToDisplay; public final String[] gmtOffsetStrings; public final TimeZone[] timeZones; public final Set<String> localZoneIds; public final int zoneCount; public ZoneGetterData(Context context) { final Locale locale = Locale.getDefault(); final Date now = new Date(); final List<String> olsonIdsToDisplayList = readTimezonesToDisplay(context); // Load all the data needed to display time zones zoneCount = olsonIdsToDisplayList.size(); olsonIdsToDisplay = new String[zoneCount]; timeZones = new TimeZone[zoneCount]; gmtOffsetStrings = new String[zoneCount]; for (int i = 0; i < zoneCount; i++) { final String olsonId = olsonIdsToDisplayList.get(i); olsonIdsToDisplay[i] = olsonId; final TimeZone tz = TimeZone.getTimeZone(olsonId); timeZones[i] = tz; gmtOffsetStrings[i] = getGmtOffsetString(locale, tz, now); } // Create a lookup of local zone IDs. localZoneIds = new HashSet<String>(); for (String olsonId : libcore.icu.TimeZoneNames.forLocale(locale)) { localZoneIds.add(olsonId); } } } } No newline at end of file
packages/SettingsLib/tests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.MANAGE_USERS" /> <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/> <uses-permission android:name="android.permission.SET_TIME_ZONE" /> <application> <uses-library android:name="android.test.runner" /> Loading
packages/SettingsLib/tests/src/com/android/settingslib/utils/ZoneGetterTest.java 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 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.utils; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.support.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.*; import com.android.settingslib.datetime.ZoneGetter; import static junit.framework.Assert.assertTrue; @RunWith(AndroidJUnit4.class) @SmallTest public class ZoneGetterTest { private static final String TIME_ZONE_LONDON_ID = "Europe/London"; private static final String TIME_ZONE_LA_ID = "America/Los_Angeles"; private Locale mLocaleEnUs; private Calendar mCalendar; @Before public void setUp() { mLocaleEnUs = new Locale("en", "us"); Locale.setDefault(mLocaleEnUs); mCalendar = new GregorianCalendar(2016, 9, 1); } @Test public void getTimeZoneOffsetAndName_setLondon_returnLondon() { // Check it will ends with 'London', not 'British Summer Time' or sth else testTimeZoneOffsetAndNameInner(TIME_ZONE_LONDON_ID, "London"); } @Test public void getTimeZoneOffsetAndName_setLosAngeles_returnPacificDaylightTime() { // Check it will ends with 'Pacific Daylight Time', not 'Los_Angeles' testTimeZoneOffsetAndNameInner(TIME_ZONE_LA_ID, "Pacific Daylight Time"); } private void testTimeZoneOffsetAndNameInner(String timeZoneId, String expectedName) { final Context context = InstrumentationRegistry.getContext(); final TimeZone timeZone = TimeZone.getTimeZone(timeZoneId); String timeZoneString = ZoneGetter.getTimeZoneOffsetAndName(context, timeZone, mCalendar.getTime()); assertTrue(timeZoneString.endsWith(expectedName)); } }