Merge "Allow alternative time zone ID to be set device's zone." am: 2cd0b0aadf

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Settings/+/1652336

Change-Id: If30061d2e580c2cbb0a9ca2dc00f66604264a02d
This commit is contained in:
Almaz Mingaleev
2021-03-30 08:57:53 +00:00
committed by Automerger Merge Worker
7 changed files with 64 additions and 27 deletions

View File

@@ -71,14 +71,14 @@ public class RegionSearchPicker extends BaseTimeZonePicker {
final FilteredCountryTimeZones countryTimeZones = mTimeZoneData.lookupCountryTimeZones( final FilteredCountryTimeZones countryTimeZones = mTimeZoneData.lookupCountryTimeZones(
regionId); regionId);
final Activity activity = getActivity(); final Activity activity = getActivity();
if (countryTimeZones == null || countryTimeZones.getTimeZoneIds().isEmpty()) { if (countryTimeZones == null || countryTimeZones.getPreferredTimeZoneIds().isEmpty()) {
Log.e(TAG, "Region has no time zones: " + regionId); Log.e(TAG, "Region has no time zones: " + regionId);
activity.setResult(Activity.RESULT_CANCELED); activity.setResult(Activity.RESULT_CANCELED);
activity.finish(); activity.finish();
return; return;
} }
List<String> timeZoneIds = countryTimeZones.getTimeZoneIds(); List<String> timeZoneIds = countryTimeZones.getPreferredTimeZoneIds();
// Choose the time zone associated the region if there is only one time zone in that region // Choose the time zone associated the region if there is only one time zone in that region
if (timeZoneIds.size() == 1) { if (timeZoneIds.size() == 1) {
final Intent resultData = new Intent() final Intent resultData = new Intent()

View File

@@ -103,7 +103,7 @@ public class RegionZonePicker extends BaseTimeZoneInfoPicker {
// It could be a timely operations if there are many time zones. A region in time zone data // It could be a timely operations if there are many time zones. A region in time zone data
// contains a maximum of 29 time zones currently. It may change in the future, but it's // contains a maximum of 29 time zones currently. It may change in the future, but it's
// unlikely to be changed drastically. // unlikely to be changed drastically.
return getRegionTimeZoneInfo(filteredCountryTimeZones.getTimeZoneIds()); return getRegionTimeZoneInfo(filteredCountryTimeZones.getPreferredTimeZoneIds());
} }
/** /**

View File

@@ -214,10 +214,11 @@ public class TimeZoneSettings extends DashboardFragment {
mTimeZoneData.lookupCountryTimeZones(regionId); mTimeZoneData.lookupCountryTimeZones(regionId);
use(RegionZonePreferenceController.class).setTimeZoneInfo(tzInfo); use(RegionZonePreferenceController.class).setTimeZoneInfo(tzInfo);
// Only clickable when the region has more than 1 time zones or no time zone is selected.
// Only clickable when the region has more than 1 time zones or no time zone is selected.
use(RegionZonePreferenceController.class).setClickable(tzInfo == null || use(RegionZonePreferenceController.class).setClickable(tzInfo == null ||
(countryTimeZones != null && countryTimeZones.getTimeZoneIds().size() > 1)); (countryTimeZones != null
&& countryTimeZones.getPreferredTimeZoneIds().size() > 1));
use(TimeZoneInfoPreferenceController.class).setTimeZoneInfo(tzInfo); use(TimeZoneInfoPreferenceController.class).setTimeZoneInfo(tzInfo);
updatePreferenceStates(); updatePreferenceStates();
@@ -244,7 +245,8 @@ public class TimeZoneSettings extends DashboardFragment {
FilteredCountryTimeZones countryTimeZones = FilteredCountryTimeZones countryTimeZones =
timeZoneData.lookupCountryTimeZones(regionId); timeZoneData.lookupCountryTimeZones(regionId);
if (countryTimeZones == null || !countryTimeZones.getTimeZoneIds().contains(tzId)) { if (countryTimeZones == null
|| !countryTimeZones.getPreferredTimeZoneIds().contains(tzId)) {
Log.e(TAG, "Unknown time zone id is selected: " + tzId); Log.e(TAG, "Unknown time zone id is selected: " + tzId);
return; return;
} }

View File

@@ -16,11 +16,15 @@
package com.android.settings.datetime.timezone.model; package com.android.settings.datetime.timezone.model;
import android.util.ArraySet;
import com.android.i18n.timezone.CountryTimeZones; import com.android.i18n.timezone.CountryTimeZones;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.Set;
/** /**
* Wrap {@class CountryTimeZones} to filter time zone that are shown in the picker. * Wrap {@class CountryTimeZones} to filter time zone that are shown in the picker.
@@ -39,31 +43,46 @@ public class FilteredCountryTimeZones {
* a timestamp known to be in the recent past is used. This should be updated occasionally but * a timestamp known to be in the recent past is used. This should be updated occasionally but
* it doesn't have to be very often. * it doesn't have to be very often.
*/ */
private static final long MIN_USE_DATE_OF_TIMEZONE = 1546300800000L; // 1/1/2019 00:00 UTC private static final Instant MIN_USE_DATE_OF_TIMEZONE =
Instant.ofEpochMilli(1546300800000L); // 1/1/2019 00:00 UTC
private final CountryTimeZones mCountryTimeZones; private final CountryTimeZones mCountryTimeZones;
private final List<String> mTimeZoneIds; private final List<String> mPreferredTimeZoneIds;
private final Set<String> mAlternativeTimeZoneIds;
public FilteredCountryTimeZones(CountryTimeZones countryTimeZones) { public FilteredCountryTimeZones(CountryTimeZones countryTimeZones) {
mCountryTimeZones = countryTimeZones; mCountryTimeZones = countryTimeZones;
List<String> timeZoneIds = countryTimeZones.getTimeZoneMappings().stream() List<String> timeZoneIds = new ArrayList<>();
.filter(timeZoneMapping -> Set<String> alternativeTimeZoneIds = new ArraySet<>();
timeZoneMapping.isShownInPicker() for (CountryTimeZones.TimeZoneMapping timeZoneMapping :
&& (timeZoneMapping.getNotUsedAfter() == null countryTimeZones.getTimeZoneMappings()) {
|| timeZoneMapping.getNotUsedAfter() >= MIN_USE_DATE_OF_TIMEZONE)) if (timeZoneMapping.isShownInPickerAt(MIN_USE_DATE_OF_TIMEZONE)) {
.map(timeZoneMapping -> timeZoneMapping.getTimeZoneId()) String timeZoneId = timeZoneMapping.getTimeZoneId();
.collect(Collectors.toList()); timeZoneIds.add(timeZoneId);
mTimeZoneIds = Collections.unmodifiableList(timeZoneIds); alternativeTimeZoneIds.addAll(timeZoneMapping.getAlternativeIds());
}
}
mPreferredTimeZoneIds = Collections.unmodifiableList(timeZoneIds);
mAlternativeTimeZoneIds = Collections.unmodifiableSet(alternativeTimeZoneIds);
} }
public List<String> getTimeZoneIds() { public List<String> getPreferredTimeZoneIds() {
return mTimeZoneIds; return mPreferredTimeZoneIds;
} }
public CountryTimeZones getCountryTimeZones() { public CountryTimeZones getCountryTimeZones() {
return mCountryTimeZones; return mCountryTimeZones;
} }
/**
* Returns whether {@code timeZoneId} is currently used in the country or is an alternative
* name of a currently used time zone.
*/
public boolean matches(String timeZoneId) {
return mPreferredTimeZoneIds.contains(timeZoneId)
|| mAlternativeTimeZoneIds.contains(timeZoneId);
}
public String getRegionId() { public String getRegionId() {
return TimeZoneData.normalizeRegionId(mCountryTimeZones.getCountryIso()); return TimeZoneData.normalizeRegionId(mCountryTimeZones.getCountryIso());
} }

View File

@@ -71,7 +71,7 @@ public class TimeZoneData {
Set<String> regionIds = new ArraySet<>(); Set<String> regionIds = new ArraySet<>();
for (CountryTimeZones countryTimeZone : countryTimeZones) { for (CountryTimeZones countryTimeZone : countryTimeZones) {
FilteredCountryTimeZones filteredZones = new FilteredCountryTimeZones(countryTimeZone); FilteredCountryTimeZones filteredZones = new FilteredCountryTimeZones(countryTimeZone);
if (filteredZones.getTimeZoneIds().contains(tzId)) { if (filteredZones.matches(tzId)) {
regionIds.add(filteredZones.getRegionId()); regionIds.add(filteredZones.getRegionId());
} }
} }

View File

@@ -92,4 +92,23 @@ public class TimeZoneDataTest {
.containsExactly("US", "GB"); .containsExactly("US", "GB");
assertThat(timeZoneData.lookupCountryCodesForZoneId("Unknown/Secret_City2")).isEmpty(); assertThat(timeZoneData.lookupCountryCodesForZoneId("Unknown/Secret_City2")).isEmpty();
} }
@Test
public void lookupCountryCodesForNonCanonicalZoneId_returnsCurrentZone() {
TimeZoneData timeZoneData = new TimeZoneData(mCountryZonesFinder);
CountryTimeZones greenland = mock(CountryTimeZones.class);
when(greenland.getCountryIso()).thenReturn("gl");
when(greenland.getTimeZoneMappings()).thenReturn(Arrays.asList(
TimeZoneMapping.createForTests(
"America/Nuuk",
true /* showInPicker */,
null /* notUsedAfter */,
Arrays.asList("America/Godthab"))));
when(mCountryZonesFinder.lookupCountryTimeZonesForZoneId("America/Godthab"))
.thenReturn(Arrays.asList(greenland));
assertThat(timeZoneData.lookupCountryCodesForZoneId("America/Godthab"))
.containsExactly("GL");
}
} }

View File

@@ -43,7 +43,7 @@ public class TimeZoneDataTest {
FilteredCountryTimeZones countryTimeZones = FilteredCountryTimeZones countryTimeZones =
mTimeZoneData.lookupCountryTimeZones(regionId); mTimeZoneData.lookupCountryTimeZones(regionId);
assertThat(countryTimeZones).isNotNull(); assertThat(countryTimeZones).isNotNull();
assertThat(countryTimeZones.getTimeZoneIds().size()).isGreaterThan(0); assertThat(countryTimeZones.getPreferredTimeZoneIds().size()).isGreaterThan(0);
} }
} }
@@ -54,11 +54,8 @@ public class TimeZoneDataTest {
1) because we specifically exclude it with the picker attribute, and 1) because we specifically exclude it with the picker attribute, and
2) because it's the same as Moscow after Oct 2014. 2) because it's the same as Moscow after Oct 2014.
*/ */
assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/Simferopol").isEmpty()) assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/Simferopol")).isEmpty();
.isTrue(); assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/London")).isNotEmpty();
assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/London").isEmpty()) assertThat(mTimeZoneData.lookupCountryCodesForZoneId("America/Los_Angeles")).isNotEmpty();
.isFalse();
assertThat(mTimeZoneData.lookupCountryCodesForZoneId("America/Los_Angeles").isEmpty())
.isFalse();
} }
} }