Merge "Add TimeZoneProviderEventPreProcessor." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
286535874d
@@ -47,7 +47,7 @@ class BinderLocationTimeZoneProvider extends LocationTimeZoneProvider {
|
|||||||
@NonNull String providerName,
|
@NonNull String providerName,
|
||||||
@NonNull LocationTimeZoneProviderProxy proxy) {
|
@NonNull LocationTimeZoneProviderProxy proxy) {
|
||||||
super(providerMetricsLogger, threadingDomain, providerName,
|
super(providerMetricsLogger, threadingDomain, providerName,
|
||||||
new ZoneInfoDbTimeZoneIdValidator());
|
new ZoneInfoDbTimeZoneProviderEventPreProcessor());
|
||||||
mProxy = Objects.requireNonNull(proxy);
|
mProxy = Objects.requireNonNull(proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESU
|
|||||||
import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESULT_SUCCESS_KEY;
|
import static android.service.timezone.TimeZoneProviderService.TEST_COMMAND_RESULT_SUCCESS_KEY;
|
||||||
|
|
||||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.debugLog;
|
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.debugLog;
|
||||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.infoLog;
|
|
||||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
|
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
|
||||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DESTROYED;
|
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DESTROYED;
|
||||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
|
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_PERM_FAILED;
|
||||||
@@ -85,18 +84,6 @@ abstract class LocationTimeZoneProvider implements Dumpable {
|
|||||||
void onProviderStateChange(@NonNull ProviderState providerState);
|
void onProviderStateChange(@NonNull ProviderState providerState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by {@link LocationTimeZoneProvider} to check if time zone IDs are understood
|
|
||||||
* by the platform.
|
|
||||||
*/
|
|
||||||
interface TimeZoneIdValidator {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether {@code timeZoneId} is supported by the platform or not.
|
|
||||||
*/
|
|
||||||
boolean isValid(@NonNull String timeZoneId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener interface used to log provider events for metrics.
|
* Listener interface used to log provider events for metrics.
|
||||||
*/
|
*/
|
||||||
@@ -386,19 +373,20 @@ abstract class LocationTimeZoneProvider implements Dumpable {
|
|||||||
// Non-null and effectively final after initialize() is called.
|
// Non-null and effectively final after initialize() is called.
|
||||||
ProviderListener mProviderListener;
|
ProviderListener mProviderListener;
|
||||||
|
|
||||||
@NonNull private TimeZoneIdValidator mTimeZoneIdValidator;
|
@NonNull private final TimeZoneProviderEventPreProcessor mTimeZoneProviderEventPreProcessor;
|
||||||
|
|
||||||
/** Creates the instance. */
|
/** Creates the instance. */
|
||||||
LocationTimeZoneProvider(@NonNull ProviderMetricsLogger providerMetricsLogger,
|
LocationTimeZoneProvider(@NonNull ProviderMetricsLogger providerMetricsLogger,
|
||||||
@NonNull ThreadingDomain threadingDomain,
|
@NonNull ThreadingDomain threadingDomain,
|
||||||
@NonNull String providerName,
|
@NonNull String providerName,
|
||||||
@NonNull TimeZoneIdValidator timeZoneIdValidator) {
|
@NonNull TimeZoneProviderEventPreProcessor timeZoneProviderEventPreProcessor) {
|
||||||
mThreadingDomain = Objects.requireNonNull(threadingDomain);
|
mThreadingDomain = Objects.requireNonNull(threadingDomain);
|
||||||
mProviderMetricsLogger = Objects.requireNonNull(providerMetricsLogger);
|
mProviderMetricsLogger = Objects.requireNonNull(providerMetricsLogger);
|
||||||
mInitializationTimeoutQueue = threadingDomain.createSingleRunnableQueue();
|
mInitializationTimeoutQueue = threadingDomain.createSingleRunnableQueue();
|
||||||
mSharedLock = threadingDomain.getLockObject();
|
mSharedLock = threadingDomain.getLockObject();
|
||||||
mProviderName = Objects.requireNonNull(providerName);
|
mProviderName = Objects.requireNonNull(providerName);
|
||||||
mTimeZoneIdValidator = Objects.requireNonNull(timeZoneIdValidator);
|
mTimeZoneProviderEventPreProcessor =
|
||||||
|
Objects.requireNonNull(timeZoneProviderEventPreProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -639,24 +627,8 @@ abstract class LocationTimeZoneProvider implements Dumpable {
|
|||||||
mThreadingDomain.assertCurrentThread();
|
mThreadingDomain.assertCurrentThread();
|
||||||
Objects.requireNonNull(timeZoneProviderEvent);
|
Objects.requireNonNull(timeZoneProviderEvent);
|
||||||
|
|
||||||
// If the provider has made a suggestion with unknown time zone IDs it cannot be used to set
|
timeZoneProviderEvent =
|
||||||
// the device's time zone. This logic prevents bad time zone IDs entering the time zone
|
mTimeZoneProviderEventPreProcessor.preProcess(timeZoneProviderEvent);
|
||||||
// detection logic from third party code.
|
|
||||||
//
|
|
||||||
// An event containing an unknown time zone ID could occur if the provider is using a
|
|
||||||
// different TZDB version than the device. Provider developers are expected to take steps to
|
|
||||||
// avoid version skew problem, e.g. by ensuring atomic updates with the platform time zone
|
|
||||||
// rules, or providing IDs based on the device's TZDB version, so this is not considered a
|
|
||||||
// common case.
|
|
||||||
//
|
|
||||||
// Treating a suggestion containing unknown time zone IDs as "uncertain" in the primary
|
|
||||||
// enables immediate failover to a secondary provider, one that might provide valid IDs for
|
|
||||||
// the same location, which should provide better behavior than just ignoring the event.
|
|
||||||
if (hasInvalidTimeZones(timeZoneProviderEvent)) {
|
|
||||||
infoLog("event=" + timeZoneProviderEvent + " has unsupported time zones. "
|
|
||||||
+ "Replacing it with uncertain event.");
|
|
||||||
timeZoneProviderEvent = TimeZoneProviderEvent.createUncertainEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mSharedLock) {
|
synchronized (mSharedLock) {
|
||||||
debugLog("handleTimeZoneProviderEvent: mProviderName=" + mProviderName
|
debugLog("handleTimeZoneProviderEvent: mProviderName=" + mProviderName
|
||||||
@@ -755,20 +727,6 @@ abstract class LocationTimeZoneProvider implements Dumpable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasInvalidTimeZones(@NonNull TimeZoneProviderEvent event) {
|
|
||||||
if (event.getSuggestion() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String timeZone : event.getSuggestion().getTimeZoneIds()) {
|
|
||||||
if (!mTimeZoneIdValidator.isValid(timeZone)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GuardedBy("mSharedLock")
|
@GuardedBy("mSharedLock")
|
||||||
private void assertIsStarted() {
|
private void assertIsStarted() {
|
||||||
ProviderState currentState = mCurrentState.get();
|
ProviderState currentState = mCurrentState.get();
|
||||||
|
|||||||
@@ -18,13 +18,16 @@ package com.android.server.timezonedetector.location;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.i18n.timezone.ZoneInfoDb;
|
/**
|
||||||
|
* Used by {@link LocationTimeZoneProvider} to ensure that all time zone IDs are understood by the
|
||||||
|
* platform.
|
||||||
|
*/
|
||||||
|
public interface TimeZoneProviderEventPreProcessor {
|
||||||
|
|
||||||
class ZoneInfoDbTimeZoneIdValidator implements
|
/**
|
||||||
LocationTimeZoneProvider.TimeZoneIdValidator {
|
* May return uncertain event if {@code timeZoneProviderEvent} is ill-formed or drop/rewrite
|
||||||
|
* time zone IDs.
|
||||||
|
*/
|
||||||
|
TimeZoneProviderEvent preProcess(@NonNull TimeZoneProviderEvent timeZoneProviderEvent);
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValid(@NonNull String timeZoneId) {
|
|
||||||
return ZoneInfoDb.getInstance().hasTimeZone(timeZoneId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.server.timezonedetector.location;
|
||||||
|
|
||||||
|
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.infoLog;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.android.i18n.timezone.ZoneInfoDb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TimeZoneProviderEventPreProcessor} implementation which makes validations against
|
||||||
|
* {@link ZoneInfoDb}.
|
||||||
|
*/
|
||||||
|
public class ZoneInfoDbTimeZoneProviderEventPreProcessor
|
||||||
|
implements TimeZoneProviderEventPreProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns uncertain event if {@code event} has at least one unsupported time zone ID.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TimeZoneProviderEvent preProcess(@NonNull TimeZoneProviderEvent event) {
|
||||||
|
if (event.getSuggestion() == null || event.getSuggestion().getTimeZoneIds().isEmpty()) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the provider has made a suggestion with unknown time zone IDs it cannot be used to set
|
||||||
|
// the device's time zone. This logic prevents bad time zone IDs entering the time zone
|
||||||
|
// detection logic from third party code.
|
||||||
|
//
|
||||||
|
// An event containing an unknown time zone ID could occur if the provider is using a
|
||||||
|
// different TZDB version than the device. Provider developers are expected to take steps to
|
||||||
|
// avoid version skew problem, e.g. by ensuring atomic updates with the platform time zone
|
||||||
|
// rules, or providing IDs based on the device's TZDB version, so this is not considered a
|
||||||
|
// common case.
|
||||||
|
//
|
||||||
|
// Treating a suggestion containing unknown time zone IDs as "uncertain" in the primary
|
||||||
|
// enables immediate failover to a secondary provider, one that might provide valid IDs for
|
||||||
|
// the same location, which should provide better behavior than just ignoring the event.
|
||||||
|
if (hasInvalidZones(event)) {
|
||||||
|
return TimeZoneProviderEvent.createUncertainEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasInvalidZones(TimeZoneProviderEvent event) {
|
||||||
|
for (String timeZone : event.getSuggestion().getTimeZoneIds()) {
|
||||||
|
if (!ZoneInfoDb.getInstance().hasTimeZone(timeZone)) {
|
||||||
|
infoLog("event=" + event + " has unsupported zone(" + timeZone + ")");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -72,7 +72,6 @@ public class ControllerImplTest {
|
|||||||
private TestCallback mTestCallback;
|
private TestCallback mTestCallback;
|
||||||
private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider;
|
private TestLocationTimeZoneProvider mTestPrimaryLocationTimeZoneProvider;
|
||||||
private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider;
|
private TestLocationTimeZoneProvider mTestSecondaryLocationTimeZoneProvider;
|
||||||
private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -84,13 +83,10 @@ public class ControllerImplTest {
|
|||||||
};
|
};
|
||||||
mTestThreadingDomain = new TestThreadingDomain();
|
mTestThreadingDomain = new TestThreadingDomain();
|
||||||
mTestCallback = new TestCallback(mTestThreadingDomain);
|
mTestCallback = new TestCallback(mTestThreadingDomain);
|
||||||
mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
|
|
||||||
mTestPrimaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
|
mTestPrimaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
|
||||||
stubbedProviderMetricsLogger, mTestThreadingDomain, "primary",
|
stubbedProviderMetricsLogger, mTestThreadingDomain, "primary");
|
||||||
mTimeZoneAvailabilityChecker);
|
|
||||||
mTestSecondaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
|
mTestSecondaryLocationTimeZoneProvider = new TestLocationTimeZoneProvider(
|
||||||
stubbedProviderMetricsLogger, mTestThreadingDomain, "secondary",
|
stubbedProviderMetricsLogger, mTestThreadingDomain, "secondary");
|
||||||
mTimeZoneAvailabilityChecker);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1185,10 +1181,9 @@ public class ControllerImplTest {
|
|||||||
* Creates the instance.
|
* Creates the instance.
|
||||||
*/
|
*/
|
||||||
TestLocationTimeZoneProvider(ProviderMetricsLogger providerMetricsLogger,
|
TestLocationTimeZoneProvider(ProviderMetricsLogger providerMetricsLogger,
|
||||||
ThreadingDomain threadingDomain, String providerName,
|
ThreadingDomain threadingDomain, String providerName) {
|
||||||
TimeZoneIdValidator timeZoneIdValidator) {
|
|
||||||
super(providerMetricsLogger, threadingDomain, providerName,
|
super(providerMetricsLogger, threadingDomain, providerName,
|
||||||
timeZoneIdValidator);
|
new FakeTimeZoneProviderEventPreProcessor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFailDuringInitialization(boolean failInitialization) {
|
public void setFailDuringInitialization(boolean failInitialization) {
|
||||||
@@ -1321,14 +1316,4 @@ public class ControllerImplTest {
|
|||||||
mTestProviderState.commitLatest();
|
mTestProviderState.commitLatest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class FakeTimeZoneIdValidator
|
|
||||||
implements LocationTimeZoneProvider.TimeZoneIdValidator {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValid(@NonNull String timeZoneId) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.server.timezonedetector.location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fake implementation of {@link TimeZoneProviderEventPreProcessor} which assumes that all events
|
||||||
|
* are valid or always uncertain if {@link #enterUncertainMode()} was called.
|
||||||
|
*/
|
||||||
|
public final class FakeTimeZoneProviderEventPreProcessor
|
||||||
|
implements TimeZoneProviderEventPreProcessor {
|
||||||
|
|
||||||
|
private boolean mIsUncertain = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeZoneProviderEvent preProcess(TimeZoneProviderEvent timeZoneProviderEvent) {
|
||||||
|
if (mIsUncertain) {
|
||||||
|
return TimeZoneProviderEvent.createUncertainEvent();
|
||||||
|
}
|
||||||
|
return timeZoneProviderEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enterUncertainMode() {
|
||||||
|
mIsUncertain = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,10 +52,8 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,13 +66,13 @@ public class LocationTimeZoneProviderTest {
|
|||||||
|
|
||||||
private TestThreadingDomain mTestThreadingDomain;
|
private TestThreadingDomain mTestThreadingDomain;
|
||||||
private TestProviderListener mProviderListener;
|
private TestProviderListener mProviderListener;
|
||||||
private FakeTimeZoneIdValidator mTimeZoneAvailabilityChecker;
|
private FakeTimeZoneProviderEventPreProcessor mTimeZoneProviderEventPreProcessor;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
mTestThreadingDomain = new TestThreadingDomain();
|
mTestThreadingDomain = new TestThreadingDomain();
|
||||||
mProviderListener = new TestProviderListener();
|
mProviderListener = new TestProviderListener();
|
||||||
mTimeZoneAvailabilityChecker = new FakeTimeZoneIdValidator();
|
mTimeZoneProviderEventPreProcessor = new FakeTimeZoneProviderEventPreProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -82,9 +80,10 @@ public class LocationTimeZoneProviderTest {
|
|||||||
String providerName = "arbitrary";
|
String providerName = "arbitrary";
|
||||||
RecordingProviderMetricsLogger providerMetricsLogger = new RecordingProviderMetricsLogger();
|
RecordingProviderMetricsLogger providerMetricsLogger = new RecordingProviderMetricsLogger();
|
||||||
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
||||||
providerMetricsLogger, mTestThreadingDomain, providerName,
|
providerMetricsLogger,
|
||||||
mTimeZoneAvailabilityChecker);
|
mTestThreadingDomain,
|
||||||
mTimeZoneAvailabilityChecker.validIds("Europe/London");
|
providerName,
|
||||||
|
mTimeZoneProviderEventPreProcessor);
|
||||||
|
|
||||||
// initialize()
|
// initialize()
|
||||||
provider.initialize(mProviderListener);
|
provider.initialize(mProviderListener);
|
||||||
@@ -174,8 +173,10 @@ public class LocationTimeZoneProviderTest {
|
|||||||
String providerName = "primary";
|
String providerName = "primary";
|
||||||
StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
|
StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
|
||||||
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
||||||
providerMetricsLogger, mTestThreadingDomain, providerName,
|
providerMetricsLogger,
|
||||||
mTimeZoneAvailabilityChecker);
|
mTestThreadingDomain,
|
||||||
|
providerName,
|
||||||
|
mTimeZoneProviderEventPreProcessor);
|
||||||
|
|
||||||
TestCommand testCommand = TestCommand.createForTests("test", new Bundle());
|
TestCommand testCommand = TestCommand.createForTests("test", new Bundle());
|
||||||
AtomicReference<Bundle> resultReference = new AtomicReference<>();
|
AtomicReference<Bundle> resultReference = new AtomicReference<>();
|
||||||
@@ -193,10 +194,11 @@ public class LocationTimeZoneProviderTest {
|
|||||||
String providerName = "primary";
|
String providerName = "primary";
|
||||||
StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
|
StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
|
||||||
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
||||||
providerMetricsLogger, mTestThreadingDomain, providerName,
|
providerMetricsLogger,
|
||||||
mTimeZoneAvailabilityChecker);
|
mTestThreadingDomain,
|
||||||
|
providerName,
|
||||||
|
mTimeZoneProviderEventPreProcessor);
|
||||||
provider.setStateChangeRecordingEnabled(true);
|
provider.setStateChangeRecordingEnabled(true);
|
||||||
mTimeZoneAvailabilityChecker.validIds("Europe/London");
|
|
||||||
|
|
||||||
// initialize()
|
// initialize()
|
||||||
provider.initialize(mProviderListener);
|
provider.initialize(mProviderListener);
|
||||||
@@ -234,14 +236,17 @@ public class LocationTimeZoneProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void considerSuggestionWithInvalidTimeZoneIdsAsUncertain() {
|
public void entersUncertainState_whenEventHasUnsupportedZones() {
|
||||||
String providerName = "primary";
|
String providerName = "primary";
|
||||||
StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
|
StubbedProviderMetricsLogger providerMetricsLogger = new StubbedProviderMetricsLogger();
|
||||||
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
TestLocationTimeZoneProvider provider = new TestLocationTimeZoneProvider(
|
||||||
providerMetricsLogger, mTestThreadingDomain, providerName,
|
providerMetricsLogger,
|
||||||
mTimeZoneAvailabilityChecker);
|
mTestThreadingDomain,
|
||||||
|
providerName,
|
||||||
|
mTimeZoneProviderEventPreProcessor);
|
||||||
provider.setStateChangeRecordingEnabled(true);
|
provider.setStateChangeRecordingEnabled(true);
|
||||||
provider.initialize(mProviderListener);
|
provider.initialize(mProviderListener);
|
||||||
|
mTimeZoneProviderEventPreProcessor.enterUncertainMode();
|
||||||
|
|
||||||
ConfigurationInternal config = USER1_CONFIG_GEO_DETECTION_ENABLED;
|
ConfigurationInternal config = USER1_CONFIG_GEO_DETECTION_ENABLED;
|
||||||
Duration arbitraryInitializationTimeout = Duration.ofMinutes(5);
|
Duration arbitraryInitializationTimeout = Duration.ofMinutes(5);
|
||||||
@@ -309,8 +314,9 @@ public class LocationTimeZoneProviderTest {
|
|||||||
TestLocationTimeZoneProvider(@NonNull ProviderMetricsLogger providerMetricsLogger,
|
TestLocationTimeZoneProvider(@NonNull ProviderMetricsLogger providerMetricsLogger,
|
||||||
@NonNull ThreadingDomain threadingDomain,
|
@NonNull ThreadingDomain threadingDomain,
|
||||||
@NonNull String providerName,
|
@NonNull String providerName,
|
||||||
@NonNull TimeZoneIdValidator timeZoneIdValidator) {
|
@NonNull TimeZoneProviderEventPreProcessor timeZoneProviderEventPreProcessor) {
|
||||||
super(providerMetricsLogger, threadingDomain, providerName, timeZoneIdValidator);
|
super(providerMetricsLogger,
|
||||||
|
threadingDomain, providerName, timeZoneProviderEventPreProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -367,20 +373,6 @@ public class LocationTimeZoneProviderTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class FakeTimeZoneIdValidator
|
|
||||||
implements LocationTimeZoneProvider.TimeZoneIdValidator {
|
|
||||||
private final Set<String> mValidTimeZoneIds = new HashSet<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isValid(@NonNull String timeZoneId) {
|
|
||||||
return mValidTimeZoneIds.contains(timeZoneId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validIds(String... timeZoneIdss) {
|
|
||||||
mValidTimeZoneIds.addAll(asList(timeZoneIdss));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class StubbedProviderMetricsLogger implements
|
private static class StubbedProviderMetricsLogger implements
|
||||||
LocationTimeZoneProvider.ProviderMetricsLogger {
|
LocationTimeZoneProvider.ProviderMetricsLogger {
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.timezonedetector.location;
|
|||||||
import static com.google.common.truth.Truth.assertWithMessage;
|
import static com.google.common.truth.Truth.assertWithMessage;
|
||||||
|
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
import android.service.timezone.TimeZoneProviderSuggestion;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -26,29 +27,44 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/** Tests for {@link ZoneInfoDbTimeZoneProviderEventPreProcessor}. */
|
||||||
@Presubmit
|
@Presubmit
|
||||||
public class ZoneInfoDbTimeZoneIdValidatorTest {
|
public class ZoneInfoDbTimeZoneProviderEventPreProcessorTest {
|
||||||
private final LocationTimeZoneProvider.TimeZoneIdValidator mTzChecker =
|
|
||||||
new ZoneInfoDbTimeZoneIdValidator();
|
private static final long ARBITRARY_TIME_MILLIS = 11223344;
|
||||||
|
|
||||||
|
private final ZoneInfoDbTimeZoneProviderEventPreProcessor mPreProcessor =
|
||||||
|
new ZoneInfoDbTimeZoneProviderEventPreProcessor();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void timeZoneIdsFromZoneInfoDbAreValid() {
|
public void timeZoneIdsFromZoneInfoDbAreValid() {
|
||||||
for (String timeZone : TimeZone.getAvailableIDs()) {
|
for (String timeZone : TimeZone.getAvailableIDs()) {
|
||||||
|
TimeZoneProviderEvent event = timeZoneProviderEvent(timeZone);
|
||||||
assertWithMessage("Time zone %s should be supported", timeZone)
|
assertWithMessage("Time zone %s should be supported", timeZone)
|
||||||
.that(mTzChecker.isValid(timeZone)).isTrue();
|
.that(mPreProcessor.preProcess(event)).isEqualTo(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nonExistingZones_areNotSupported() {
|
public void eventWithNonExistingZones_areMappedToUncertainEvent() {
|
||||||
List<String> nonExistingTimeZones = Arrays.asList(
|
List<String> nonExistingTimeZones = Arrays.asList(
|
||||||
"SystemV/HST10", "Atlantic/Atlantis", "EUROPE/LONDON", "Etc/GMT-5:30"
|
"SystemV/HST10", "Atlantic/Atlantis", "EUROPE/LONDON", "Etc/GMT-5:30");
|
||||||
);
|
|
||||||
|
|
||||||
for (String timeZone : nonExistingTimeZones) {
|
for (String timeZone : nonExistingTimeZones) {
|
||||||
|
TimeZoneProviderEvent event = timeZoneProviderEvent(timeZone);
|
||||||
|
|
||||||
assertWithMessage(timeZone + " is not a valid time zone")
|
assertWithMessage(timeZone + " is not a valid time zone")
|
||||||
.that(mTzChecker.isValid(timeZone))
|
.that(mPreProcessor.preProcess(event))
|
||||||
.isFalse();
|
.isEqualTo(TimeZoneProviderEvent.createUncertainEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TimeZoneProviderEvent timeZoneProviderEvent(String... timeZoneIds) {
|
||||||
|
return TimeZoneProviderEvent.createSuggestionEvent(
|
||||||
|
new TimeZoneProviderSuggestion.Builder()
|
||||||
|
.setTimeZoneIds(Arrays.asList(timeZoneIds))
|
||||||
|
.setElapsedRealtimeMillis(ARBITRARY_TIME_MILLIS)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user