aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Fuller <nfuller@google.com>2020-12-14 20:59:15 +0000
committerNeil Fuller <nfuller@google.com>2020-12-15 22:19:39 +0000
commit37d8e591073bac94199cec3ca97e86e79f82fe2b (patch)
tree788765416680c7c1291e84d570e3f55c067428fa
parent74199467ae8a5858b14e58e8d49306fb67746326 (diff)
downloadGeoTZ-37d8e591073bac94199cec3ca97e86e79f82fe2b.tar.gz
Switch to android.service APIs
Switch the OfflineTimeZoneProvider to new, cleaner System APIs. Bug: 175633818 Test: build / treehugger Change-Id: If4a772e6063a464bd7166e6cd08653ea7485c330
-rw-r--r--apex/com.android.geotz/Android.bp2
-rw-r--r--locationtzprovider/Android.bp8
-rw-r--r--locationtzprovider/src/main/java/com/android/timezone/geotz/provider/EnvironmentImpl.java17
-rw-r--r--locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProvider.java81
-rw-r--r--locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProviderService.java95
-rw-r--r--locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneService.java73
-rw-r--r--locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/Mode.java66
-rw-r--r--locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegate.java175
-rw-r--r--locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/TimeZoneProviderResult.java142
-rw-r--r--locationtzprovider/src/test/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegateTest.java30
10 files changed, 381 insertions, 308 deletions
diff --git a/apex/com.android.geotz/Android.bp b/apex/com.android.geotz/Android.bp
index aec1a84..6fad0fa 100644
--- a/apex/com.android.geotz/Android.bp
+++ b/apex/com.android.geotz/Android.bp
@@ -62,7 +62,7 @@ java_library {
static_libs: [
"offlinelocationtimezoneprovider",
],
- sdk_version: "current",
+ sdk_version: "system_current",
apex_available: [
"com.android.geotz",
],
diff --git a/locationtzprovider/Android.bp b/locationtzprovider/Android.bp
index c25e887..9c3c4b5 100644
--- a/locationtzprovider/Android.bp
+++ b/locationtzprovider/Android.bp
@@ -17,10 +17,9 @@
java_library {
name: "offlinelocationtimezoneprovider",
srcs: ["src/main/java/**/*.java"],
- sdk_version: "current",
+ sdk_version: "system_current",
libs: [
"androidx.annotation_annotation",
- "com.android.location.provider",
],
static_libs: [
"geotz_lookup",
@@ -35,10 +34,7 @@ android_test {
name: "OfflineLocationTimeZoneProviderTests",
srcs: ["src/test/java/**/*.java"],
manifest: "src/test/AndroidManifest.xml",
- sdk_version: "current",
- libs: [
- "com.android.location.provider",
- ],
+ sdk_version: "system_current",
static_libs: [
"androidx.test.runner",
"junit",
diff --git a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/EnvironmentImpl.java b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/EnvironmentImpl.java
index 60fc294..a29078d 100644
--- a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/EnvironmentImpl.java
+++ b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/EnvironmentImpl.java
@@ -32,11 +32,11 @@ import android.os.SystemClock;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.location.timezone.provider.LocationTimeZoneEventUnbundled;
import com.android.timezone.geotz.lookup.GeoTimeZonesFinder;
import com.android.timezone.geotz.provider.core.Cancellable;
import com.android.timezone.geotz.provider.core.OfflineLocationTimeZoneDelegate;
import com.android.timezone.geotz.provider.core.OfflineLocationTimeZoneDelegate.ListenModeEnum;
+import com.android.timezone.geotz.provider.core.TimeZoneProviderResult;
import java.io.File;
import java.io.IOException;
@@ -63,15 +63,14 @@ class EnvironmentImpl implements OfflineLocationTimeZoneDelegate.Environment {
@NonNull
private final Handler mHandler;
@NonNull
- private final Consumer<LocationTimeZoneEventUnbundled> mEventConsumer;
+ private final Consumer<TimeZoneProviderResult> mResultConsumer;
@NonNull
private final File mGeoDataFile;
- EnvironmentImpl(
- @NonNull Context context,
- @NonNull Consumer<LocationTimeZoneEventUnbundled> eventConsumer) {
+ EnvironmentImpl(@NonNull Context context,
+ @NonNull Consumer<TimeZoneProviderResult> resultConsumer) {
mLocationManager = context.getSystemService(LocationManager.class);
- mEventConsumer = Objects.requireNonNull(eventConsumer);
+ mResultConsumer = Objects.requireNonNull(resultConsumer);
mHandler = new Handler(Looper.getMainLooper());
Properties configProperties = loadConfigProperties(getClass().getClassLoader());
@@ -97,7 +96,7 @@ class EnvironmentImpl implements OfflineLocationTimeZoneDelegate.Environment {
@Override
@NonNull
public <T> Cancellable startTimeout(@Nullable Consumer<T> callback, @NonNull T callbackToken,
- @NonNull long delayMillis) {
+ long delayMillis) {
// Deliberate use of an anonymous class as the equality of lambdas is not well defined but
// instance equality is required for the remove call.
@@ -213,8 +212,8 @@ class EnvironmentImpl implements OfflineLocationTimeZoneDelegate.Environment {
}
@Override
- public void reportLocationTimeZoneEvent(@NonNull LocationTimeZoneEventUnbundled event) {
- mEventConsumer.accept(event);
+ public void reportTimeZoneProviderResult(@NonNull TimeZoneProviderResult result) {
+ mResultConsumer.accept(result);
}
@Override
diff --git a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProvider.java b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProvider.java
deleted file mode 100644
index a11e667..0000000
--- a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2020 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.timezone.geotz.provider;
-
-import android.content.Context;
-
-import androidx.annotation.NonNull;
-
-import com.android.location.timezone.provider.LocationTimeZoneProviderBase;
-import com.android.location.timezone.provider.LocationTimeZoneProviderRequestUnbundled;
-import com.android.timezone.geotz.provider.core.LogUtils;
-import com.android.timezone.geotz.provider.core.OfflineLocationTimeZoneDelegate;
-import com.android.timezone.geotz.provider.core.OfflineLocationTimeZoneDelegate.Environment;
-
-import java.io.PrintWriter;
-
-/**
- * A Location Time Zone Provider implementation that uses only Android public SDK APIs and on-device
- * data to determine the current time zone(s) for a location.
- *
- * <p>This implementation can be deployed to run as either the current user (e.g. it could run in a
- * user-specific process like GMS core), or always as the system user (e.g. it can run in a single
- * user process like system server). It relies on being disabled by the system server when the user
- * changes. No location state is retained when the provider is disabled.
- *
- * <p>See {@link OfflineLocationTimeZoneDelegate} for implementation details.
- *
- * <p>The provider is configured via a "offlineltzprovider.properties" resource file. See
- * {@link EnvironmentImpl} for details.
- */
-final class OfflineLocationTimeZoneProvider extends LocationTimeZoneProviderBase {
-
- private static final String ATTRIBUTION_TAG = "OfflineLocationTimeZoneProvider";
-
- @NonNull
- private final OfflineLocationTimeZoneDelegate mDelegate;
-
- OfflineLocationTimeZoneProvider(@NonNull Context context) {
- super(context, LogUtils.LOG_TAG);
- Context attributionContext = context.createAttributionContext(ATTRIBUTION_TAG);
- Environment environment = new EnvironmentImpl(
- attributionContext, this::reportLocationTimeZoneEvent);
- mDelegate = new OfflineLocationTimeZoneDelegate(environment);
- }
-
- public void onBind() {
- mDelegate.onBind();
- }
-
- public void onDestroy() {
- mDelegate.onDestroy();
- }
-
- @Override
- protected void onSetRequest(@NonNull LocationTimeZoneProviderRequestUnbundled request) {
- if (request.getReportLocationTimeZone()) {
- mDelegate.onEnable(request.getInitializationTimeoutMillis());
- } else {
- mDelegate.onDisable();
- }
- }
-
- public void dump(@NonNull PrintWriter pw) {
- mDelegate.dump(pw);
- }
-
-} \ No newline at end of file
diff --git a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProviderService.java b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProviderService.java
new file mode 100644
index 0000000..d108f3c
--- /dev/null
+++ b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneProviderService.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2020 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.timezone.geotz.provider;
+
+import android.content.Context;
+import android.service.timezone.TimeZoneProviderService;
+
+import androidx.annotation.NonNull;
+
+import com.android.timezone.geotz.provider.core.OfflineLocationTimeZoneDelegate;
+import com.android.timezone.geotz.provider.core.OfflineLocationTimeZoneDelegate.Environment;
+import com.android.timezone.geotz.provider.core.TimeZoneProviderResult;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * A Location Time Zone Provider implementation that uses only Android public SDK APIs and on-device
+ * data to determine the current time zone(s) for a location.
+ *
+ * <p>This implementation can be deployed to run as either the current user (e.g. it could run in a
+ * user-specific process like GMS core), or always as the system user (e.g. it can run in a single
+ * user process like system server). It relies on being stopped by the system server when the user
+ * changes. No location state is retained when the provider is stopped.
+ *
+ * <p>See {@link OfflineLocationTimeZoneDelegate} for implementation details.
+ *
+ * <p>The provider is configured via a "offlineltzprovider.properties" resource file. See
+ * {@link EnvironmentImpl} for details.
+ */
+public final class OfflineLocationTimeZoneProviderService extends TimeZoneProviderService {
+
+ private static final String ATTRIBUTION_TAG = "OfflineLocationTimeZoneProviderService";
+
+ // NonNull after onCreate()
+ private OfflineLocationTimeZoneDelegate mDelegate;
+
+ @Override
+ public void onCreate() {
+ Context attributionContext = createAttributionContext(ATTRIBUTION_TAG);
+ Environment environment = new EnvironmentImpl(
+ attributionContext, this::reportTimeZoneProviderEvent);
+ mDelegate = new OfflineLocationTimeZoneDelegate(environment);
+ }
+
+ @Override
+ public void onStartUpdates(long initializationTimeoutMillis) {
+ mDelegate.onStartUpdates(initializationTimeoutMillis);
+ }
+
+ private void reportTimeZoneProviderEvent(
+ @NonNull TimeZoneProviderResult timeZoneProviderResult) {
+ switch (timeZoneProviderResult.getType()) {
+ case TimeZoneProviderResult.RESULT_TYPE_SUGGESTION: {
+ reportSuggestion(timeZoneProviderResult.getSuggestion());
+ break;
+ }
+ case TimeZoneProviderResult.RESULT_TYPE_UNCERTAIN: {
+ reportUncertain();
+ break;
+ }
+ case TimeZoneProviderResult.RESULT_TYPE_PERMANENT_FAILURE: {
+ reportPermanentFailure(timeZoneProviderResult.getFailureCause());
+ break;
+ }
+ default: {
+ throw new IllegalArgumentException("Unknown result type=" + timeZoneProviderResult);
+ }
+ }
+ }
+
+ @Override
+ public void onStopUpdates() {
+ mDelegate.onStopUpdates();
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ mDelegate.dump(writer);
+ }
+} \ No newline at end of file
diff --git a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneService.java b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneService.java
deleted file mode 100644
index fe4f1e6..0000000
--- a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/OfflineLocationTimeZoneService.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 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.timezone.geotz.provider;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-import androidx.annotation.Nullable;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * The service that provides the {@link OfflineLocationTimeZoneProvider}. An instance of this
- * service is discovered via configuration in an {@code AndroidManifest.xml}.
- *
- * <p>See {@link com.android.server.location.timezone.LocationTimeZoneManagerService} for the server
- * component that binds to it and how it is discovered.
- *
- * <p>See {@link com.android.server.ServiceWatcher} for how to control how the service is treated
- * and how the server resolves to a single service if there are multiple available.
- */
-public final class OfflineLocationTimeZoneService extends Service {
-
- private final Object mLock = new Object();
- @Nullable
- private OfflineLocationTimeZoneProvider mProvider;
-
- @Override
- public IBinder onBind(Intent intent) {
- synchronized (mLock) {
- if (mProvider == null) {
- mProvider = new OfflineLocationTimeZoneProvider(this);
- mProvider.onBind();
- }
- return mProvider.getBinder();
- }
- }
-
- @Override
- public void onDestroy() {
- synchronized (mLock) {
- if (mProvider != null) {
- mProvider.onDestroy();
- mProvider = null;
- }
- }
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- synchronized (mLock) {
- if (mProvider != null) {
- mProvider.dump(writer);
- }
- }
- }
-}
diff --git a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/Mode.java b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/Mode.java
index ad0f02b..dcf4621 100644
--- a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/Mode.java
+++ b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/Mode.java
@@ -42,31 +42,31 @@ import java.util.Objects;
* <p>See the docs for each {@code MODE_} constant for an explanation of each mode.
*
* <pre>
- * The initial mode is {@link #MODE_DISABLED}.
+ * The initial mode is {@link #MODE_STOPPED}.
*
* Valid transitions:
*
- * {@link #MODE_DISABLED}
- * -> {@link #MODE_ENABLED}(1)
- * - when the LTZP first receives an enabled request it starts listening for the current
+ * {@link #MODE_STOPPED}
+ * -> {@link #MODE_STARTED}(1)
+ * - when the LTZP first receives an started request it starts listening for the current
* location with {@link OfflineLocationTimeZoneDelegate#LOCATION_LISTEN_MODE_HIGH}.
- * {@link #MODE_ENABLED}(1)
- * -> {@link #MODE_ENABLED}(2)
+ * {@link #MODE_STARTED}(1)
+ * -> {@link #MODE_STARTED}(2)
* - when the LTZP receives a valid location, or if it is unable to determine the current
* location within the mode timeout, it moves to {@link
* OfflineLocationTimeZoneDelegate#LOCATION_LISTEN_MODE_LOW}
- * -> {@link #MODE_DISABLED}
- * - when the system server sends a "disabled" request the LTZP is disabled.
- * {@link #MODE_ENABLED}(2)
- * -> {@link #MODE_ENABLED}(1)
+ * -> {@link #MODE_STOPPED}
+ * - when the system server sends a "stopped" request the LTZP is stopped.
+ * {@link #MODE_STARTED}(2)
+ * -> {@link #MODE_STARTED}(1)
* - when no valid location has been received within the mode timeout, the LTZP will start
* listening for the current location using {@link
* OfflineLocationTimeZoneDelegate#LOCATION_LISTEN_MODE_HIGH}.
- * -> {@link #MODE_ENABLED}(2)
+ * -> {@link #MODE_STARTED}(2)
* - when the LTZP receives a valid location, it stays in {@link
* OfflineLocationTimeZoneDelegate#LOCATION_LISTEN_MODE_LOW}
- * -> {@link #MODE_DISABLED}
- * - when the system server sends a "disabled" request the LTZP is disabled.
+ * -> {@link #MODE_STOPPED}
+ * - when the system server sends a "stopped" request the LTZP is stopped.
*
* {All states}
* -> {@link #MODE_FAILED} (terminal state)
@@ -78,21 +78,21 @@ import java.util.Objects;
*/
class Mode {
- @IntDef({ MODE_DISABLED, MODE_ENABLED, MODE_FAILED, MODE_DESTROYED })
+ @IntDef({ MODE_STOPPED, MODE_STARTED, MODE_FAILED, MODE_DESTROYED })
@interface ModeEnum {}
/**
* An inactive state. The LTZP may not have received a request yet, or it has and the LTZP has
- * been explicitly disabled.
+ * been explicitly stopped.
*/
@ModeEnum
- static final int MODE_DISABLED = 1;
+ static final int MODE_STOPPED = 1;
/**
- * The LTZP has been enabled by the system server, and is listening for the current location.
+ * The LTZP has been started by the system server, and is listening for the current location.
*/
@ModeEnum
- static final int MODE_ENABLED = 2;
+ static final int MODE_STARTED = 2;
/**
* The LTZP's service has been destroyed.
@@ -111,7 +111,7 @@ class Mode {
final int mModeEnum;
/**
- * The current location listen mode. Only used when mModeEnum == {@link #MODE_ENABLED}.
+ * The current location listen mode. Only used when mModeEnum == {@link #MODE_STARTED}.
*/
final @ListenModeEnum int mListenMode;
@@ -134,21 +134,21 @@ class Mode {
private final String mEntryCause;
/**
- * Used when mModeEnum == {@link #MODE_ENABLED}. The {@link Cancellable} that can be
+ * Used when mModeEnum == {@link #MODE_STARTED}. The {@link Cancellable} that can be
* used to stop listening for the current location.
*/
@Nullable
private Cancellable mLocationListenerCancellable;
/**
- * Used when mModeEnum == {@link #MODE_ENABLED}. The {@link Cancellable} that can be
+ * Used when mModeEnum == {@link #MODE_STARTED}. The {@link Cancellable} that can be
* used to stop listening for the current location.
*/
@Nullable
private Cancellable mTimeoutCancellable;
/**
- * Used when mModeEnum == {@link #MODE_ENABLED} to record the token associated with the
+ * Used when mModeEnum == {@link #MODE_STARTED} to record the token associated with the
* mode timeout.
*/
@Nullable
@@ -169,15 +169,15 @@ class Mode {
mEntryCause = entryCause;
}
- /** Returns the disabled mode which is the starting state for a provider. */
+ /** Returns the stopped mode which is the starting state for a provider. */
@NonNull
- static Mode createDisabledMode() {
- return new Mode(MODE_DISABLED, "init" /* entryCause */);
+ static Mode createStoppedMode() {
+ return new Mode(MODE_STOPPED, "init" /* entryCause */);
}
/**
* Associates the supplied {@link Cancellable} with the mode to enable location listening to
- * be cancelled. Used when mModeEnum == {@link #MODE_ENABLED}. See
+ * be cancelled. Used when mModeEnum == {@link #MODE_STARTED}. See
* {@link #cancelLocationListening()}.
*/
void setLocationListenerCancellable(@NonNull Cancellable locationListenerCancellable) {
@@ -206,7 +206,7 @@ class Mode {
/**
* Associates the {@code timeoutToken} with the mode for later retrieval. Used for
- * {@link #MODE_ENABLED}.
+ * {@link #MODE_STARTED}.
*/
void setTimeoutInfo(@NonNull Cancellable timeoutCancellable,
@NonNull String timeoutToken) {
@@ -252,10 +252,10 @@ class Mode {
/** Returns a string representation of the {@link ModeEnum} value provided. */
static String prettyPrintModeEnum(@ModeEnum int modeEnum) {
switch (modeEnum) {
- case MODE_DISABLED:
- return "MODE_DISABLED";
- case MODE_ENABLED:
- return "MODE_ENABLED";
+ case MODE_STOPPED:
+ return "MODE_STOPPED";
+ case MODE_STARTED:
+ return "MODE_STARTED";
case MODE_DESTROYED:
return "MODE_DESTROYED";
case MODE_FAILED:
@@ -280,7 +280,7 @@ class Mode {
}
private static @ModeEnum int validateModeEnum(@ModeEnum int modeEnum) {
- if (modeEnum < MODE_DISABLED || modeEnum > MODE_FAILED) {
+ if (modeEnum < MODE_STOPPED || modeEnum > MODE_FAILED) {
throw new IllegalArgumentException("modeEnum=" + modeEnum);
}
return modeEnum;
@@ -288,7 +288,7 @@ class Mode {
private static @ListenModeEnum int validateListenModeEnum(
@ModeEnum int modeEnum, @ListenModeEnum int listenMode) {
- if (modeEnum == MODE_ENABLED) {
+ if (modeEnum == MODE_STARTED) {
if (listenMode != LOCATION_LISTEN_MODE_HIGH && listenMode != LOCATION_LISTEN_MODE_LOW) {
throw new IllegalArgumentException();
}
diff --git a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegate.java b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegate.java
index fef030a..f127343 100644
--- a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegate.java
+++ b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegate.java
@@ -22,19 +22,19 @@ import static com.android.timezone.geotz.provider.core.LogUtils.logDebug;
import static com.android.timezone.geotz.provider.core.LogUtils.logWarn;
import static com.android.timezone.geotz.provider.core.Mode.MODE_DESTROYED;
import static com.android.timezone.geotz.provider.core.Mode.MODE_FAILED;
-import static com.android.timezone.geotz.provider.core.Mode.MODE_DISABLED;
-import static com.android.timezone.geotz.provider.core.Mode.MODE_ENABLED;
+import static com.android.timezone.geotz.provider.core.Mode.MODE_STARTED;
+import static com.android.timezone.geotz.provider.core.Mode.MODE_STOPPED;
import static com.android.timezone.geotz.provider.core.Mode.prettyPrintListenModeEnum;
import android.location.Location;
import android.os.SystemClock;
+import android.service.timezone.TimeZoneProviderSuggestion;
import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.location.timezone.provider.LocationTimeZoneEventUnbundled;
import com.android.timezone.geotz.lookup.GeoTimeZonesFinder;
import com.android.timezone.geotz.lookup.GeoTimeZonesFinder.LocationToken;
@@ -46,9 +46,9 @@ import java.util.Objects;
import java.util.function.Consumer;
/**
- * A class encapsulating the time zone detection logic for an Offline LocationTimeZoneProvider.
- * It has been decoupled from the Android environment and many API via the {@link Environment}
- * interface to enable easier unit testing.
+ * A class encapsulating the time zone detection logic for an Offline location-based
+ * {@link android.service.timezone.TimeZoneProviderService}. It has been decoupled from the Android
+ * environment and many API via the {@link Environment} interface to enable easier unit testing.
*
* <p>The overall goal of this class is to balance power consumption with responsiveness.
*
@@ -57,19 +57,19 @@ import java.util.function.Consumer;
* <p>The instance interacts with multiple threads, but state changes occur in a single-threaded
* manner through the use of a lock object, {@link #mLock}.
*
- * <p>When first enabled, the current location is requested using {@link
+ * <p>When first started, the current location is requested using {@link
* Environment#startLocationListening(int, Consumer)} with {@link #LOCATION_LISTEN_MODE_HIGH} and
* a timeout is requested using {@link Environment#startTimeout(Consumer, Object, long)}.
*
* <p>If a valid location is found within the timeout, the time zones for the location are looked up
- * and an {@link LocationTimeZoneEventUnbundled event} is sent via {@link
- * Environment#reportLocationTimeZoneEvent(LocationTimeZoneEventUnbundled)}.
+ * and an {@link TimeZoneProviderResult result} is recorded via {@link
+ * Environment#reportTimeZoneProviderResult(TimeZoneProviderResult)}.
*
* <p>If a valid location cannot be found within the timeout, a {@link
- * LocationTimeZoneEventUnbundled#EVENT_TYPE_UNCERTAIN} {@link
- * LocationTimeZoneEventUnbundled event} is sent to the system server.
+ * TimeZoneProviderResult#RESULT_TYPE_UNCERTAIN} {@link TimeZoneProviderResult result} is recorded to the
+ * system server.
*
- * <p>After an {@link LocationTimeZoneEventUnbundled event} has been sent, the provider restarts
+ * <p>After an {@link TimeZoneProviderResult result} has been sent, the provider restarts
* location listening with a new timeout but in {@link #LOCATION_LISTEN_MODE_LOW}. If the current
* location continues to be available it will stay in this mode, extending the timeout, otherwise it
* will switch to {@link #LOCATION_LISTEN_MODE_HIGH} with a shorter timeout.
@@ -113,7 +113,7 @@ public final class OfflineLocationTimeZoneDelegate {
*/
@NonNull
<T> Cancellable startTimeout(@NonNull Consumer<T> callback,
- @Nullable T callbackToken, @NonNull long delayMillis);
+ @Nullable T callbackToken, long delayMillis);
/**
* Starts an async location lookup. The location passed to {@code locationListener} will not
@@ -134,7 +134,7 @@ public final class OfflineLocationTimeZoneDelegate {
/**
* Used to report location time zone information.
*/
- void reportLocationTimeZoneEvent(@NonNull LocationTimeZoneEventUnbundled event);
+ void reportTimeZoneProviderResult(@NonNull TimeZoneProviderResult result);
/** See {@link SystemClock#elapsedRealtime()}. */
long elapsedRealtimeMillis();
@@ -157,16 +157,17 @@ public final class OfflineLocationTimeZoneDelegate {
private LocationToken mLastLocationToken;
/**
- * The last location time zone event sent by the provider. Currently used for debugging only.
+ * The last time zone provider result determined by the provider. Currently used for debugging
+ * only.
*/
@GuardedBy("mLock")
- private final ReferenceWithHistory<LocationTimeZoneEventUnbundled> mLastLocationTimeZoneEvent =
+ private final ReferenceWithHistory<TimeZoneProviderResult> mLastTimeZoneProviderResult =
new ReferenceWithHistory<>(10);
public OfflineLocationTimeZoneDelegate(@NonNull Environment environment) {
mEnvironment = Objects.requireNonNull(environment);
- mCurrentMode.set(Mode.createDisabledMode());
+ mCurrentMode.set(Mode.createStoppedMode());
}
public void onBind() {
@@ -175,13 +176,13 @@ public final class OfflineLocationTimeZoneDelegate {
synchronized (mLock) {
Mode currentMode = mCurrentMode.get();
- if (currentMode.mModeEnum != MODE_DISABLED) {
+ if (currentMode.mModeEnum != MODE_STOPPED) {
handleUnexpectedStateTransition(
"onBind() called when in unexpected mode=" + currentMode);
return;
}
- Mode newMode = new Mode(MODE_DISABLED, entryCause);
+ Mode newMode = new Mode(MODE_STOPPED, entryCause);
mCurrentMode.set(newMode);
}
}
@@ -194,35 +195,35 @@ public final class OfflineLocationTimeZoneDelegate {
cancelTimeoutAndLocationCallbacks();
Mode currentMode = mCurrentMode.get();
- if (currentMode.mModeEnum == MODE_ENABLED) {
- sendTimeZoneUncertainEventIfNeeded();
+ if (currentMode.mModeEnum == MODE_STARTED) {
+ sendTimeZoneUncertainResultIfNeeded();
}
Mode newMode = new Mode(MODE_DESTROYED, entryCause);
mCurrentMode.set(newMode);
}
}
- public void onDisable() {
- String debugInfo = "onDisable()";
+ public void onStopUpdates() {
+ String debugInfo = "onStopUpdates()";
logDebug(debugInfo);
synchronized (mLock) {
Mode currentMode = mCurrentMode.get();
switch (currentMode.mModeEnum) {
- case MODE_DISABLED: {
- // No-op - the provider is already disabled.
- logWarn("Unexpected onDisable() when currentMode=" + currentMode);
+ case MODE_STOPPED: {
+ // No-op - the provider is already stopped.
+ logWarn("Unexpected onStopUpdates() when currentMode=" + currentMode);
break;
}
- case MODE_ENABLED: {
- enterDisabledMode(debugInfo);
+ case MODE_STARTED: {
+ enterStoppedMode(debugInfo);
break;
}
case MODE_FAILED:
case MODE_DESTROYED:
default: {
handleUnexpectedStateTransition(
- "Unexpected onDisable() when currentMode=" + currentMode);
+ "Unexpected onStopUpdates() when currentMode=" + currentMode);
break;
}
}
@@ -230,31 +231,32 @@ public final class OfflineLocationTimeZoneDelegate {
}
- public void onEnable(@NonNull long initializationTimeoutMillis) {
- String debugInfo = "onEnable(), initializationTimeoutMillis=" + initializationTimeoutMillis;
+ public void onStartUpdates(long initializationTimeoutMillis) {
+ String debugInfo = "onStartUpdates(),"
+ + " initializationTimeoutMillis=" + initializationTimeoutMillis;
logDebug(debugInfo);
synchronized (mLock) {
Mode currentMode = mCurrentMode.get();
switch (currentMode.mModeEnum) {
- case MODE_DISABLED: {
+ case MODE_STOPPED: {
// Always start in the most aggressive location listening mode. The request
// contains the time in which the LTZP is given to provide the first
- // event, so this is used for the first timeout.
+ // result, so this is used for the first timeout.
enterLocationListeningMode(LOCATION_LISTEN_MODE_HIGH, debugInfo,
initializationTimeoutMillis);
break;
}
- case MODE_ENABLED: {
- // No-op - the provider is already enabled.
- logWarn("Unexpected onEnabled() received when in currentMode=" + currentMode);
+ case MODE_STARTED: {
+ // No-op - the provider is already started.
+ logWarn("Unexpected onStarted() received when in currentMode=" + currentMode);
break;
}
case MODE_FAILED:
case MODE_DESTROYED:
default: {
handleUnexpectedStateTransition(
- "Unexpected onEnabled() received when in currentMode=" + currentMode);
+ "Unexpected onStarted() received when in currentMode=" + currentMode);
break;
}
}
@@ -268,17 +270,13 @@ public final class OfflineLocationTimeZoneDelegate {
+ formatElapsedRealtimeMillis(mEnvironment.elapsedRealtimeMillis()));
pw.println("mCurrentMode=" + mCurrentMode);
pw.println("mLastLocationToken=" + mLastLocationToken);
- pw.println("mLastLocationTimeZoneEvent=" + mLastLocationTimeZoneEvent);
+ pw.println("mLastTimeZoneProviderResult=" + mLastTimeZoneProviderResult);
pw.println();
pw.println("Mode history:");
- // pw.increaseIndent();
mCurrentMode.dump(pw);
- // pw.decreaseIndent();
pw.println();
- pw.println("LocationTimeZoneEvent history:");
- // pw.increaseIndent();
- mLastLocationTimeZoneEvent.dump(pw);
- // pw.decreaseIndent();
+ pw.println("TimeZoneProviderResult history:");
+ mLastTimeZoneProviderResult.dump(pw);
}
}
@@ -289,7 +287,7 @@ public final class OfflineLocationTimeZoneDelegate {
}
/**
- * Accepts the current location when in {@link Mode#MODE_ENABLED}.
+ * Accepts the current location when in {@link Mode#MODE_STARTED}.
*/
private void onLocationReceived(@NonNull Location location) {
Objects.requireNonNull(location);
@@ -297,7 +295,7 @@ public final class OfflineLocationTimeZoneDelegate {
synchronized (mLock) {
Mode currentMode = mCurrentMode.get();
- if (currentMode.mModeEnum != MODE_ENABLED) {
+ if (currentMode.mModeEnum != MODE_STARTED) {
// This is not expected to happen.
String unexpectedStateDebugInfo = "Unexpected call to onLocationReceived(),"
+ " location=" + location
@@ -313,7 +311,7 @@ public final class OfflineLocationTimeZoneDelegate {
// A good location has been received.
try {
- sendTimeZoneCertainEventIfNeeded(location);
+ sendTimeZoneCertainResultIfNeeded(location);
// Move to the least aggressive location listening mode.
enterLocationListeningMode(LOCATION_LISTEN_MODE_LOW, debugInfo,
@@ -324,7 +322,7 @@ public final class OfflineLocationTimeZoneDelegate {
+ " previous debugInfo=" + debugInfo;
logWarn(lookupFailureDebugInfo, e);
- enterFailedMode(lookupFailureDebugInfo);
+ enterFailedMode(new IOException(lookupFailureDebugInfo, e));
}
}
}
@@ -339,7 +337,7 @@ public final class OfflineLocationTimeZoneDelegate {
synchronized (mLock) {
Mode currentMode = mCurrentMode.get();
- if (currentMode.mModeEnum != MODE_ENABLED) {
+ if (currentMode.mModeEnum != MODE_STARTED) {
handleUnexpectedCallback("Unexpected timeout for mode=" + currentMode);
return;
}
@@ -350,7 +348,7 @@ public final class OfflineLocationTimeZoneDelegate {
}
if (currentMode.mListenMode == LOCATION_LISTEN_MODE_HIGH) {
- sendTimeZoneUncertainEventIfNeeded();
+ sendTimeZoneUncertainResultIfNeeded();
enterLocationListeningMode(LOCATION_LISTEN_MODE_LOW, debugInfo,
LOCATION_LISTEN_MODE_LOW_TIMEOUT_MILLIS);
} else {
@@ -361,7 +359,7 @@ public final class OfflineLocationTimeZoneDelegate {
}
@GuardedBy("mLock")
- private void sendTimeZoneCertainEventIfNeeded(@NonNull Location location)
+ private void sendTimeZoneCertainResultIfNeeded(@NonNull Location location)
throws IOException {
try (GeoTimeZonesFinder geoTimeZonesFinder = mEnvironment.createGeoTimeZoneFinder()) {
// Convert the location to a LocationToken.
@@ -369,61 +367,59 @@ public final class OfflineLocationTimeZoneDelegate {
location.getLatitude(), location.getLongitude());
// If the location token is the same as the last lookup, there is no need to do the
- // lookup / send another event.
+ // lookup / send another suggestion.
if (locationToken.equals(mLastLocationToken)) {
logDebug("Location token=" + locationToken + " has not changed.");
} else {
List<String> tzIds =
geoTimeZonesFinder.findTimeZonesForLocationToken(locationToken);
logDebug("tzIds found for location=" + location + ", tzIds=" + tzIds);
- LocationTimeZoneEventUnbundled event =
- new LocationTimeZoneEventUnbundled.Builder()
- .setEventType(LocationTimeZoneEventUnbundled.EVENT_TYPE_SUCCESS)
- .setTimeZoneIds(tzIds)
- .build();
- reportLocationTimeZoneEventInternal(event, locationToken);
+ TimeZoneProviderSuggestion suggestion = new TimeZoneProviderSuggestion.Builder()
+ .setTimeZoneIds(tzIds)
+ .setElapsedRealtimeMillis(mEnvironment.elapsedRealtimeMillis())
+ .build();
+
+ TimeZoneProviderResult result =
+ TimeZoneProviderResult.createSuggestion(suggestion);
+ reportTimeZoneProviderResultInternal(result, locationToken);
}
}
}
@GuardedBy("mLock")
- private void sendTimeZoneUncertainEventIfNeeded() {
- LocationTimeZoneEventUnbundled lastEvent = mLastLocationTimeZoneEvent.get();
-
- // If the last event was uncertain, there is no need to send another.
- if (lastEvent == null ||
- lastEvent.getEventType() != LocationTimeZoneEventUnbundled.EVENT_TYPE_UNCERTAIN) {
- LocationTimeZoneEventUnbundled event = new LocationTimeZoneEventUnbundled.Builder()
- .setEventType(LocationTimeZoneEventUnbundled.EVENT_TYPE_UNCERTAIN)
- .build();
- reportLocationTimeZoneEventInternal(event, null /* locationToken */);
+ private void sendTimeZoneUncertainResultIfNeeded() {
+ TimeZoneProviderResult lastResult = mLastTimeZoneProviderResult.get();
+
+ // If the last result was uncertain, there is no need to send another.
+ if (lastResult == null ||
+ lastResult.getType() != TimeZoneProviderResult.RESULT_TYPE_UNCERTAIN) {
+ TimeZoneProviderResult result = TimeZoneProviderResult.createUncertain();
+ reportTimeZoneProviderResultInternal(result, null /* locationToken */);
} else {
- logDebug("sendTimeZoneUncertainEventIfNeeded(): Last event=" + lastEvent
+ logDebug("sendTimeZoneUncertainResultIfNeeded(): Last result=" + lastResult
+ ", no need to sent another.");
}
}
@GuardedBy("mLock")
- private void sendPermanentFailureEvent() {
- LocationTimeZoneEventUnbundled event = new LocationTimeZoneEventUnbundled.Builder()
- .setEventType(LocationTimeZoneEventUnbundled.EVENT_TYPE_PERMANENT_FAILURE)
- .build();
- reportLocationTimeZoneEventInternal(event, null /* locationToken */);
+ private void sendPermanentFailureResult(@NonNull Throwable cause) {
+ TimeZoneProviderResult result = TimeZoneProviderResult.createPermanentFailure(cause);
+ reportTimeZoneProviderResultInternal(result, null /* locationToken */);
}
@GuardedBy("mLock")
- private void reportLocationTimeZoneEventInternal(
- @NonNull LocationTimeZoneEventUnbundled event,
+ private void reportTimeZoneProviderResultInternal(
+ @NonNull TimeZoneProviderResult result,
@Nullable LocationToken locationToken) {
- mLastLocationTimeZoneEvent.set(event);
+ mLastTimeZoneProviderResult.set(result);
mLastLocationToken = locationToken;
- mEnvironment.reportLocationTimeZoneEvent(event);
+ mEnvironment.reportTimeZoneProviderResult(result);
}
@GuardedBy("mLock")
private void clearLocationState() {
mLastLocationToken = null;
- mLastLocationTimeZoneEvent.set(null);
+ mLastTimeZoneProviderResult.set(null);
}
/** Called when leaving the current mode to cancel all pending asynchronous operations. */
@@ -449,35 +445,36 @@ public final class OfflineLocationTimeZoneDelegate {
}
@GuardedBy("mLock")
- private void enterFailedMode(@NonNull String entryCause) {
+ private void enterFailedMode(@NonNull Throwable entryCause) {
logDebug("Provider entering failed mode, entryCause=" + entryCause);
cancelTimeoutAndLocationCallbacks();
- sendPermanentFailureEvent();
+ sendPermanentFailureResult(entryCause);
- Mode newMode = new Mode(MODE_FAILED, entryCause);
+ String failureReason = entryCause.getMessage();
+ Mode newMode = new Mode(MODE_FAILED, failureReason);
mCurrentMode.set(newMode);
}
@GuardedBy("mLock")
- private void enterDisabledMode(@NonNull String entryCause) {
- logDebug("Provider entering disabled mode, entryCause=" + entryCause);
+ private void enterStoppedMode(@NonNull String entryCause) {
+ logDebug("Provider entering stopped mode, entryCause=" + entryCause);
cancelTimeoutAndLocationCallbacks();
- // Clear all location-derived state. The provider may be disabled due to the current user
+ // Clear all location-derived state. The provider may be stopped due to the current user
// changing.
clearLocationState();
- Mode newMode = new Mode(MODE_DISABLED, entryCause);
+ Mode newMode = new Mode(MODE_STOPPED, entryCause);
mCurrentMode.set(newMode);
}
@GuardedBy("mLock")
private void enterLocationListeningMode(
@ListenModeEnum int listenMode,
- @NonNull String entryCause, @NonNull long timeoutMillis) {
+ @NonNull String entryCause, long timeoutMillis) {
logDebug("Provider entering location listening mode"
+ ", listenMode=" + prettyPrintListenModeEnum(listenMode)
+ ", entryCause=" + entryCause);
@@ -485,8 +482,8 @@ public final class OfflineLocationTimeZoneDelegate {
Mode currentMode = mCurrentMode.get();
currentMode.cancelTimeout();
- Mode newMode = new Mode(MODE_ENABLED, entryCause, listenMode);
- if (currentMode.mModeEnum != MODE_ENABLED
+ Mode newMode = new Mode(MODE_STARTED, entryCause, listenMode);
+ if (currentMode.mModeEnum != MODE_STARTED
|| currentMode.mListenMode != listenMode) {
currentMode.cancelLocationListening();
Cancellable locationListenerCancellable =
diff --git a/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/TimeZoneProviderResult.java b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/TimeZoneProviderResult.java
new file mode 100644
index 0000000..7633412
--- /dev/null
+++ b/locationtzprovider/src/main/java/com/android/timezone/geotz/provider/core/TimeZoneProviderResult.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2020 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.timezone.geotz.provider.core;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import android.service.timezone.TimeZoneProviderService;
+import android.service.timezone.TimeZoneProviderSuggestion;
+
+import java.util.Objects;
+
+/**
+ * A result of a period of time zone detection.
+ */
+public final class TimeZoneProviderResult {
+
+ @IntDef({ RESULT_TYPE_PERMANENT_FAILURE, RESULT_TYPE_SUGGESTION, RESULT_TYPE_UNCERTAIN })
+ public @interface ResultType {}
+
+ /**
+ * The provider failed permanently. See {@link
+ * TimeZoneProviderService#reportPermanentFailure(Throwable)}
+ */
+ public static final int RESULT_TYPE_PERMANENT_FAILURE = 1;
+
+ /**
+ * The provider made a suggestion. See {@link
+ * TimeZoneProviderService#reportSuggestion(TimeZoneProviderSuggestion)}
+ */
+ public static final int RESULT_TYPE_SUGGESTION = 2;
+
+ /**
+ * The provider was uncertain about the time zone. See {@link
+ * TimeZoneProviderService#reportUncertain()}
+ */
+ public static final int RESULT_TYPE_UNCERTAIN = 3;
+
+ private static final TimeZoneProviderResult UNCERTAIN_RESULT =
+ new TimeZoneProviderResult(RESULT_TYPE_UNCERTAIN, null, null);
+
+ private static final int RESULT_TYPE_MIN = RESULT_TYPE_PERMANENT_FAILURE;
+ private static final int RESULT_TYPE_MAX = RESULT_TYPE_UNCERTAIN;
+
+ @ResultType
+ private final int mType;
+
+ @Nullable
+ private final TimeZoneProviderSuggestion mSuggestion;
+
+ @Nullable
+ private final Throwable mFailureCause;
+
+ private TimeZoneProviderResult(@ResultType int type,
+ @Nullable TimeZoneProviderSuggestion suggestion,
+ @Nullable Throwable failureCause) {
+ mType = type;
+ mSuggestion = suggestion;
+ mFailureCause = failureCause;
+ }
+
+ /** Returns a result of type {@link #RESULT_TYPE_SUGGESTION}. */
+ public static TimeZoneProviderResult createSuggestion(
+ @NonNull TimeZoneProviderSuggestion suggestion) {
+ return new TimeZoneProviderResult(RESULT_TYPE_SUGGESTION,
+ Objects.requireNonNull(suggestion), null);
+ }
+
+ /** Returns a result of type {@link #RESULT_TYPE_UNCERTAIN}. */
+ public static TimeZoneProviderResult createUncertain() {
+ return UNCERTAIN_RESULT;
+ }
+
+ /** Returns a result of type {@link #RESULT_TYPE_PERMANENT_FAILURE}. */
+ public static TimeZoneProviderResult createPermanentFailure(@NonNull Throwable cause) {
+ return new TimeZoneProviderResult(RESULT_TYPE_PERMANENT_FAILURE, null,
+ Objects.requireNonNull(cause));
+ }
+
+ /**
+ * Returns the result type.
+ */
+ public @ResultType int getType() {
+ return mType;
+ }
+
+ /**
+ * Returns the suggestion. Populated for {@link #RESULT_TYPE_SUGGESTION}.
+ */
+ @NonNull
+ public TimeZoneProviderSuggestion getSuggestion() {
+ return mSuggestion;
+ }
+
+ /**
+ * Returns the failure cause. Populated for {@link #RESULT_TYPE_PERMANENT_FAILURE}.
+ */
+ @Nullable
+ public Throwable getFailureCause() {
+ return mFailureCause;
+ }
+
+ @Override
+ public String toString() {
+ return "TimeZoneProviderResult{"
+ + "mResultType=" + mType
+ + ", mSuggestion=" + mSuggestion;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ TimeZoneProviderResult that = (TimeZoneProviderResult) o;
+ return mType == that.mType
+ && Objects.equals(mSuggestion, that.mSuggestion);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mType, mSuggestion);
+ }
+}
diff --git a/locationtzprovider/src/test/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegateTest.java b/locationtzprovider/src/test/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegateTest.java
index 602eeb9..17aad97 100644
--- a/locationtzprovider/src/test/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegateTest.java
+++ b/locationtzprovider/src/test/java/com/android/timezone/geotz/provider/core/OfflineLocationTimeZoneDelegateTest.java
@@ -26,7 +26,6 @@ import android.location.Location;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.location.timezone.provider.LocationTimeZoneEventUnbundled;
import com.android.timezone.geotz.lookup.GeoTimeZonesFinder;
import org.junit.Before;
@@ -62,18 +61,18 @@ public class OfflineLocationTimeZoneDelegateTest {
List<String> timeZoneIds = Arrays.asList("Europe/London");
mTestGeoTimeZoneFinder.setTimeZonesForLocation(latDegrees, lngDegrees, timeZoneIds);
- assertEquals(Mode.MODE_DISABLED, mDelegate.getCurrentModeEnumForTests());
+ assertEquals(Mode.MODE_STOPPED, mDelegate.getCurrentModeEnumForTests());
mTestEnvironment.assertIsNotListening();
mTestEnvironment.assertNoTimeoutSet();
mDelegate.onBind();
- assertEquals(Mode.MODE_DISABLED, mDelegate.getCurrentModeEnumForTests());
+ assertEquals(Mode.MODE_STOPPED, mDelegate.getCurrentModeEnumForTests());
mTestEnvironment.assertIsNotListening();
mTestEnvironment.assertNoTimeoutSet();
final int initializationTimeoutMillis = 20000;
- mDelegate.onEnable(initializationTimeoutMillis);
- assertEquals(Mode.MODE_ENABLED, mDelegate.getCurrentModeEnumForTests());
+ mDelegate.onStartUpdates(initializationTimeoutMillis);
+ assertEquals(Mode.MODE_STARTED, mDelegate.getCurrentModeEnumForTests());
mTestEnvironment.assertIsListening(
OfflineLocationTimeZoneDelegate.LOCATION_LISTEN_MODE_HIGH);
mTestEnvironment.assertTimeoutSet(initializationTimeoutMillis);
@@ -83,8 +82,8 @@ public class OfflineLocationTimeZoneDelegateTest {
location.setLongitude(1.0);
mTestEnvironment.simulateCurrentLocationDetected(location);
- mTestEnvironment.assertLocationEventReported(timeZoneIds);
- assertEquals(Mode.MODE_ENABLED, mDelegate.getCurrentModeEnumForTests());
+ mTestEnvironment.assertSuggestionResult(timeZoneIds);
+ assertEquals(Mode.MODE_STARTED, mDelegate.getCurrentModeEnumForTests());
mTestEnvironment.assertIsListening(
OfflineLocationTimeZoneDelegate.LOCATION_LISTEN_MODE_LOW);
mTestEnvironment.assertTimeoutSet(
@@ -97,7 +96,7 @@ public class OfflineLocationTimeZoneDelegateTest {
private long mElapsedRealtimeMillis;
private TestLocationListenerState mLocationListeningState;
private TestTimeoutState<?> mTimeoutState;
- private LocationTimeZoneEventUnbundled mLastEvent;
+ private TimeZoneProviderResult mLastResult;
@NonNull
@Override
@@ -124,9 +123,9 @@ public class OfflineLocationTimeZoneDelegateTest {
}
@Override
- public void reportLocationTimeZoneEvent(@NonNull LocationTimeZoneEventUnbundled event) {
- assertNotNull(event);
- mLastEvent = event;
+ public void reportTimeZoneProviderResult(@NonNull TimeZoneProviderResult result) {
+ assertNotNull(result);
+ mLastResult = result;
}
@Override
@@ -157,11 +156,10 @@ public class OfflineLocationTimeZoneDelegateTest {
assertEquals(expectedTimeoutMillis, mTimeoutState.mDelayMillis);
}
- public void assertLocationEventReported(List<String> expectedTimeZoneIds) {
- assertNotNull(mLastEvent);
- assertEquals(LocationTimeZoneEventUnbundled.EVENT_TYPE_SUCCESS,
- mLastEvent.getEventType());
- assertEquals(expectedTimeZoneIds, mLastEvent.getTimeZoneIds());
+ public void assertSuggestionResult(List<String> expectedTimeZoneIds) {
+ assertNotNull(mLastResult);
+ assertEquals(TimeZoneProviderResult.RESULT_TYPE_SUGGESTION, mLastResult.getType());
+ assertEquals(expectedTimeZoneIds, mLastResult.getSuggestion().getTimeZoneIds());
}
private class TestLocationListenerState extends TestCancellable {