diff options
| author | 2022-10-12 15:04:24 +0100 | |
|---|---|---|
| committer | 2022-11-24 15:50:14 +0000 | |
| commit | 4e5a7a11df1c97e23a2a516d7be2b6c7ece72937 (patch) | |
| tree | f06720c3cce406c4a5e9a3c302c4ed3ed1f42f58 | |
| parent | 6b5d003f17374ef1ac64127d097de4e1bd39adc3 (diff) | |
Support geo-tz detection on non-telephony devices
Begin explicit support for time zone detection on devices that do not
have telephony.
Previously, stock Android devices with automatic time zone detection
were assumed to have a telephony stack, and telephony has historically
been Android's "main" time zone detection algorithm. Location-based time
zone detection has been considered an optional add-on that could be
layered on top as an alterntive to telephony-based detection.
The system time team has received requests to support automatic time
zone detection on devices that do not have a telephony stack by (solely)
offering the location-based tz detection algorithm. This commit contains
the system-server changes needed to enable this config state, i.e. so
automatic tz detection is supported on the device but only via the
location-detection algorithm.
The implications after this commit for user configuration via stock
SettingsUI code:
+ (Unchanged) For devices without automatic tz detection, the SettingsUI
presents no toggles associated with automatic time zone detection. The
user can only manually select a time zone on these devices.
+ (Unchanged) For devices with only telephony-based tz detection, the
SettingsUI shows one toggle: "Set [time zone] automatically". This is
a global setting that affects all users.
+ (Unchanged) For devices with both telephony and location-based tz
detection algorithms "supported", the SettingsUI presents two toggles:
1) "Set [time zone] automatically" (as above)
2) "Use location [to set time zone]", this is a user-scoped setting
that selects between using the location and telephony-based
detection algorithms (modulo "telephony fallback mode", which
causes telephony signals to be used in some cases even when
location-based detection is enabled).
+ (New) For devices with ONLY location-based tz detection configured /
supported, the SettingsUI presents one toggle: "Set [time zone]
automatically" (still a global setting, as above).
For the new case that this commit unlocks, there is no value to
presenting a user with "Use location" as well as "Set automatically",
since the device would have no useful behavior if "Set automatically"
were ON and "Use location" were OFF, i.e. lacking the other algorithm to
use instead. Instead, these location-algorithm-only devices DO NOT offer
a per-user choice of "Use location", and the behavior is hardcoded as if
the current user had set the "Use location" toggle to ON.
Note: No actual settings for "Use location" are stored in this new case
as using location is not an explicit choice by the user.
Another important point for devices without telephony is that they may
also lack GNSS hardware needed to get location. In, for example, GMS
devices, a device without a telephony radio and GNSS receiver is still
able to use signals like WiFi APs for detecting location, but this
ability is determined by GMS-specific user settings. Since these
location detection APIs and their associated settings are not part of
the standard Android SDK APIs, the platform cannot directly interrogate
them. Consequently, even if the user selects "Set [time zone]
automatically" on a device without telephony, this means there is no
guarantee that an LTZP that uses proprietary location detection
mechanisms will actually be able to obtain the current location.
To address this, in other changes made recently, the LTZP can now choose
to report status information via new LTZP System APIs. These APIs enable
the LTZP to tell the platform when the LTZP cannot work properly, e.g.
when location cannot be obtained because of the user's current settings
(Status: "BLOCKED_BY_SETTINGS"). New status information has also been
added in a separate commit to the TimeZoneCapabilitiesAndConfig class
used by SettingsUI.
Note: LTZPs will have to start reporting their status for SettingsUI to
get the status information, but this offers a path for LTZPs to
generically report when location-based time zone detection is degraded
or broken due to restrictions in proprietary logic.
Later commits will be needed to add widgets to hold text and status
information to SettingsUI to improve the UX, e.g. to explain when the
LTZP cannot work properly, or clarify any implications of enabling "Set
automatically".
Test: atest services/tests/servicestests/src/com/android/server/timezonedetector/
Bug: 253015306
Change-Id: Ib60109a23d0a5a7499c5dd16a2994eed4485d9c9
6 files changed, 312 insertions, 71 deletions
diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java index 0409a8416dc3..111b4f6ee2a1 100644 --- a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java +++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java @@ -109,7 +109,7 @@ public final class ConfigurationInternal { * testing only. See {@link #isGeoDetectionExecutionEnabled()} and {@link #getDetectionMode()} * for details. */ - boolean getGeoDetectionRunInBackgroundEnabled() { + boolean getGeoDetectionRunInBackgroundEnabledSetting() { return mGeoDetectionRunInBackgroundEnabled; } @@ -132,7 +132,7 @@ public final class ConfigurationInternal { * from the raw setting value. */ public boolean getAutoDetectionEnabledBehavior() { - return isAutoDetectionSupported() && mAutoDetectionEnabledSetting; + return isAutoDetectionSupported() && getAutoDetectionEnabledSetting(); } /** Returns the ID of the user this configuration is associated with. */ @@ -171,27 +171,55 @@ public final class ConfigurationInternal { * time zone. */ public @DetectionMode int getDetectionMode() { - if (!getAutoDetectionEnabledBehavior()) { + if (!isAutoDetectionSupported()) { + // Handle the easy case first: No auto detection algorithms supported must mean manual. return DETECTION_MODE_MANUAL; - } else if (isGeoDetectionSupported() && getLocationEnabledSetting() - && getGeoDetectionEnabledSetting()) { + } else if (!getAutoDetectionEnabledSetting()) { + // Auto detection algorithms are supported, but disabled by the user. + return DETECTION_MODE_MANUAL; + } else if (getGeoDetectionEnabledBehavior()) { return DETECTION_MODE_GEO; - } else { + } else if (isTelephonyDetectionSupported()) { return DETECTION_MODE_TELEPHONY; + } else { + // On devices with telephony detection support, telephony is used instead of geo when + // geo cannot be used. This "unknown" case can occur on devices with only the location + // detection algorithm supported when the user's master location setting prevents its + // use. + return DETECTION_MODE_UNKNOWN; } } + private boolean getGeoDetectionEnabledBehavior() { + // isAutoDetectionSupported() should already have been checked before calling this method. + if (isGeoDetectionSupported() && getLocationEnabledSetting()) { + if (isTelephonyDetectionSupported()) { + // This is the "normal" case for smartphones that have both telephony and geo + // detection: the user chooses which type of detection to use. + return getGeoDetectionEnabledSetting(); + } else { + // When only geo detection is supported then there is no choice for the user to + // make between detection modes, so no user setting is consulted. + return true; + } + } + return false; + } + /** * Returns true if geolocation time zone detection behavior can execute. Typically, this will * agree with {@link #getDetectionMode()}, but under rare circumstances the geolocation detector - * may be run in the background if the user's settings allow. See also {@link - * #getGeoDetectionRunInBackgroundEnabled()}. + * may be run in the background if the user's settings allow. */ public boolean isGeoDetectionExecutionEnabled() { + return getDetectionMode() == DETECTION_MODE_GEO + || getGeoDetectionRunInBackgroundEnabledBehavior(); + } + + private boolean getGeoDetectionRunInBackgroundEnabledBehavior() { return isGeoDetectionSupported() && getLocationEnabledSetting() - && ((mAutoDetectionEnabledSetting && getGeoDetectionEnabledSetting()) - || getGeoDetectionRunInBackgroundEnabled()); + && getGeoDetectionRunInBackgroundEnabledSetting(); } @NonNull @@ -216,11 +244,19 @@ public final class ConfigurationInternal { builder.setConfigureAutoDetectionEnabledCapability(configureAutoDetectionEnabledCapability); boolean deviceHasLocationTimeZoneDetection = isGeoDetectionSupported(); + boolean deviceHasTelephonyDetection = isTelephonyDetectionSupported(); + // Note: allowConfigDateTime does not restrict the ability to change location time zone // detection enabled. This is intentional as it has user privacy implications and so it - // makes sense to leave this under a user's control. + // makes sense to leave this under a user's control. The only time this is not true is + // on devices that only support location-based detection and the main auto detection setting + // is used to influence whether location can be used. final @CapabilityState int configureGeolocationDetectionEnabledCapability; - if (!deviceHasLocationTimeZoneDetection) { + if (!deviceHasLocationTimeZoneDetection || !deviceHasTelephonyDetection) { + // If the device doesn't have geolocation detection support OR it ONLY has geolocation + // detection support (no telephony) then the user doesn't need the ability to toggle the + // location-based detection on and off (the auto detection toggle is considered + // sufficient). configureGeolocationDetectionEnabledCapability = CAPABILITY_NOT_SUPPORTED; } else if (!mAutoDetectionEnabledSetting || !getLocationEnabledSetting()) { configureGeolocationDetectionEnabledCapability = CAPABILITY_NOT_APPLICABLE; diff --git a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java index aad53596fc19..59691f8a30c5 100644 --- a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java +++ b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java @@ -136,7 +136,7 @@ public final class MetricsTimeZoneDetectorState { * testing only. */ public boolean getGeoDetectionRunInBackgroundEnabled() { - return mConfigurationInternal.getGeoDetectionRunInBackgroundEnabled(); + return mConfigurationInternal.getGeoDetectionRunInBackgroundEnabledSetting(); } /** Returns true if enhanced metric collection is enabled. */ diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java index 295c5c8ad373..6ebaf14c28db 100644 --- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java +++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java @@ -279,15 +279,18 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor { final boolean autoDetectionEnabled = configuration.isAutoDetectionEnabled(); setAutoDetectionEnabledIfRequired(autoDetectionEnabled); - // Avoid writing the geo detection enabled setting for devices with settings that - // are currently overridden by server flags: otherwise we might overwrite a droidfood - // user's real setting permanently. - // Also avoid writing the geo detection enabled setting for devices that do not support - // geo time zone detection: if we wrote it down then we'd set the value explicitly, - // which would prevent detecting "default" later. That might influence what happens on - // later releases that start to support geo detection on the same hardware. + // Only write the geo detection enabled setting when its values is used, e.g.: + // 1) Devices with a setting value that is not currently overridden by server flags + // 2) Devices that support both telephony and location detection algorithms + // + // If we wrote a setting value down when it's not used then we'd be setting the value + // explicitly, which would prevent detecting the setting is in "default" state later. + // Not being able to detect if the user has actually expressed a preference could + // influence what happens on later releases that start to support geo detection on the + // user's same hardware. if (!getGeoDetectionSettingEnabledOverride().isPresent() - && isGeoTimeZoneDetectionFeatureSupported()) { + && isGeoTimeZoneDetectionFeatureSupported() + && isTelephonyTimeZoneDetectionFeatureSupported()) { final boolean geoDetectionEnabledSetting = configuration.isGeoDetectionEnabled(); setGeoDetectionEnabledSettingIfRequired(userId, geoDetectionEnabledSetting); } diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java index 3424251ea57f..12d0f3ca2425 100644 --- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java @@ -47,6 +47,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.SystemTimeZone.TimeZoneConfidence; +import com.android.server.timezonedetector.ConfigurationInternal.DetectionMode; import java.io.PrintWriter; import java.time.Duration; @@ -597,9 +598,10 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat @GuardedBy("this") private void doAutoTimeZoneDetection( @NonNull ConfigurationInternal currentUserConfig, @NonNull String detectionReason) { - // Use the correct algorithm based on the user's current configuration. If it changes, then - // detection will be re-run. - switch (currentUserConfig.getDetectionMode()) { + // Use the correct detection algorithm based on the device's config and the user's current + // configuration. If user config changes, then detection will be re-run. + @DetectionMode int detectionMode = currentUserConfig.getDetectionMode(); + switch (detectionMode) { case ConfigurationInternal.DETECTION_MODE_MANUAL: // No work to do. break; @@ -635,9 +637,14 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat case ConfigurationInternal.DETECTION_MODE_TELEPHONY: doTelephonyTimeZoneDetection(detectionReason); break; + case ConfigurationInternal.DETECTION_MODE_UNKNOWN: + // The "DETECTION_MODE_UNKNOWN" state can occur on devices with only location + // detection algorithm support and when the user's master location toggle is off. + Slog.i(LOG_TAG, "Unknown detection mode: " + detectionMode + ", is location off?"); + break; default: - Slog.wtf(LOG_TAG, "Unknown detection mode: " - + currentUserConfig.getDetectionMode()); + // Coding error + Slog.wtf(LOG_TAG, "Unknown detection mode: " + detectionMode); } } diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java index 153d746aa8ec..0d6bb8a1aa50 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/ConfigurationInternalTest.java @@ -24,6 +24,7 @@ import static android.app.time.Capabilities.CAPABILITY_POSSESSED; import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_GEO; import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_MANUAL; import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_TELEPHONY; +import static com.android.server.timezonedetector.ConfigurationInternal.DETECTION_MODE_UNKNOWN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -51,11 +52,11 @@ public class ConfigurationInternalTest { /** * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection - * is supported (and geo detection is supported) + * is supported (both telephony and geo detection are supported) */ @Test @Parameters({ "true,true", "true,false", "false,true", "false,false" }) - public void test_autoDetectionSupported_capabilitiesAndConfiguration( + public void test_telephonyAndGeoSupported_capabilitiesAndConfiguration( boolean userConfigAllowed, boolean bypassUserPolicyChecks) { ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() .setUserId(ARBITRARY_USER_ID) @@ -72,18 +73,20 @@ public class ConfigurationInternalTest { boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks); - // Auto-detection enabled. + // Auto-detection enabled, location enabled. { - ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) .build(); - assertTrue(autoOnConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getGeoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior()); - assertTrue(autoOnConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_GEO, autoOnConfig.getDetectionMode()); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertTrue(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_GEO, config.getDetectionMode()); - TimeZoneCapabilities capabilities = autoOnConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); @@ -99,24 +102,58 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOnConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertTrue(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection enabled, location disabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(false) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertFalse(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_TELEPHONY, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getSetManualTimeZoneCapability()); + } + // This has user privacy implications so it is not restricted in the same way as others. + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); assertTrue(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } // Auto-detection disabled. { - ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(false) .build(); - assertFalse(autoOffConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOffConfig.getGeoDetectionEnabledSetting()); - assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior()); - assertFalse(autoOffConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode()); + assertFalse(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); - TimeZoneCapabilities capabilities = - autoOffConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); @@ -132,7 +169,7 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_NOT_APPLICABLE, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOffConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); assertFalse(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } @@ -161,18 +198,49 @@ public class ConfigurationInternalTest { boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks); - // Auto-detection enabled. + // Auto-detection enabled, location enabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability()); + } + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertTrue(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection enabled, location disabled. { - ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(false) .build(); - assertTrue(autoOnConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getGeoDetectionEnabledSetting()); - assertFalse(autoOnConfig.getAutoDetectionEnabledBehavior()); - assertFalse(autoOnConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_MANUAL, autoOnConfig.getDetectionMode()); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertFalse(config.getLocationEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); - TimeZoneCapabilities capabilities = autoOnConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureAutoDetectionEnabledCapability()); if (userRestrictionsExpected) { @@ -183,7 +251,7 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOnConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); assertTrue(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } @@ -219,11 +287,11 @@ public class ConfigurationInternalTest { /** * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection - * is supported (and geo detection is not supported). + * is supported (telephony only). */ @Test @Parameters({ "true,true", "true,false", "false,true", "false,false" }) - public void test_geoDetectNotSupported_capabilitiesAndConfiguration( + public void test_onlyTelephonySupported_capabilitiesAndConfiguration( boolean userConfigAllowed, boolean bypassUserPolicyChecks) { ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() .setUserId(ARBITRARY_USER_ID) @@ -242,16 +310,16 @@ public class ConfigurationInternalTest { // Auto-detection enabled. { - ConfigurationInternal autoOnConfig = new ConfigurationInternal.Builder(baseConfig) + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(true) .build(); - assertTrue(autoOnConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getGeoDetectionEnabledSetting()); - assertTrue(autoOnConfig.getAutoDetectionEnabledBehavior()); - assertFalse(autoOnConfig.isGeoDetectionExecutionEnabled()); - assertEquals(DETECTION_MODE_TELEPHONY, autoOnConfig.getDetectionMode()); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_TELEPHONY, config.getDetectionMode()); - TimeZoneCapabilities capabilities = autoOnConfig.asCapabilities(bypassUserPolicyChecks); + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); @@ -266,18 +334,139 @@ public class ConfigurationInternalTest { assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabledCapability()); - TimeZoneConfiguration configuration = autoOnConfig.asConfiguration(); + TimeZoneConfiguration configuration = config.asConfiguration(); assertTrue(configuration.isAutoDetectionEnabled()); assertTrue(configuration.isGeoDetectionEnabled()); } // Auto-detection disabled. { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(false) + .build(); + assertFalse(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getGeoDetectionEnabledSetting()); + assertFalse(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_MANUAL, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability()); + } + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertFalse(configuration.isAutoDetectionEnabled()); + assertTrue(configuration.isGeoDetectionEnabled()); + } + } + + /** + * Tests {@link TimeCapabilitiesAndConfig} behavior in different scenarios when auto detection + * is supported (only geo detection) + */ + @Test + @Parameters({ "true,true", "true,false", "false,true", "false,false" }) + public void test_onlyGeoSupported_capabilitiesAndConfiguration( + boolean userConfigAllowed, boolean bypassUserPolicyChecks) { + ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() + .setUserId(ARBITRARY_USER_ID) + .setUserConfigAllowed(userConfigAllowed) + .setTelephonyDetectionFeatureSupported(false) + .setGeoDetectionFeatureSupported(true) + .setGeoDetectionRunInBackgroundEnabled(false) + .setTelephonyFallbackSupported(false) + .setEnhancedMetricsCollectionEnabled(false) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) + .setGeoDetectionEnabledSetting(false) + .build(); + + boolean userRestrictionsExpected = !(userConfigAllowed || bypassUserPolicyChecks); + + // Auto-detection enabled, location enabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(true) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertTrue(config.getLocationEnabledSetting()); + assertFalse(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertTrue(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_GEO, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getSetManualTimeZoneCapability()); + } + // This capability is always "not supported" if geo detection is the only mechanism. + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertFalse(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection enabled, location disabled. + { + ConfigurationInternal config = new ConfigurationInternal.Builder(baseConfig) + .setAutoDetectionEnabledSetting(true) + .setLocationEnabledSetting(false) + .build(); + assertTrue(config.getAutoDetectionEnabledSetting()); + assertFalse(config.getLocationEnabledSetting()); + assertFalse(config.getGeoDetectionEnabledSetting()); + assertTrue(config.getAutoDetectionEnabledBehavior()); + assertFalse(config.isGeoDetectionExecutionEnabled()); + assertEquals(DETECTION_MODE_UNKNOWN, config.getDetectionMode()); + + TimeZoneCapabilities capabilities = config.asCapabilities(bypassUserPolicyChecks); + if (userRestrictionsExpected) { + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); + } else { + assertEquals(CAPABILITY_POSSESSED, + capabilities.getConfigureAutoDetectionEnabledCapability()); + assertEquals(CAPABILITY_NOT_APPLICABLE, + capabilities.getSetManualTimeZoneCapability()); + } + // This capability is always "not supported" if geo detection is the only mechanism. + assertEquals(CAPABILITY_NOT_SUPPORTED, + capabilities.getConfigureGeoDetectionEnabledCapability()); + + TimeZoneConfiguration configuration = config.asConfiguration(); + assertTrue(configuration.isAutoDetectionEnabled()); + assertFalse(configuration.isGeoDetectionEnabled()); + } + + // Auto-detection disabled. + { ConfigurationInternal autoOffConfig = new ConfigurationInternal.Builder(baseConfig) .setAutoDetectionEnabledSetting(false) .build(); assertFalse(autoOffConfig.getAutoDetectionEnabledSetting()); - assertTrue(autoOffConfig.getGeoDetectionEnabledSetting()); + assertFalse(autoOffConfig.getGeoDetectionEnabledSetting()); assertFalse(autoOffConfig.getAutoDetectionEnabledBehavior()); assertFalse(autoOffConfig.isGeoDetectionExecutionEnabled()); assertEquals(DETECTION_MODE_MANUAL, autoOffConfig.getDetectionMode()); @@ -287,18 +476,21 @@ public class ConfigurationInternalTest { if (userRestrictionsExpected) { assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getConfigureAutoDetectionEnabledCapability()); - assertEquals(CAPABILITY_NOT_ALLOWED, capabilities.getSetManualTimeZoneCapability()); + assertEquals(CAPABILITY_NOT_ALLOWED, + capabilities.getSetManualTimeZoneCapability()); } else { assertEquals(CAPABILITY_POSSESSED, capabilities.getConfigureAutoDetectionEnabledCapability()); - assertEquals(CAPABILITY_POSSESSED, capabilities.getSetManualTimeZoneCapability()); + assertEquals(CAPABILITY_POSSESSED, + capabilities.getSetManualTimeZoneCapability()); } + // This capability is always "not supported" if geo detection is the only mechanism. assertEquals(CAPABILITY_NOT_SUPPORTED, capabilities.getConfigureGeoDetectionEnabledCapability()); TimeZoneConfiguration configuration = autoOffConfig.asConfiguration(); assertFalse(configuration.isAutoDetectionEnabled()); - assertTrue(configuration.isGeoDetectionEnabled()); + assertFalse(configuration.isGeoDetectionEnabled()); } } @@ -317,7 +509,10 @@ public class ConfigurationInternalTest { assertTrue(config.isTelephonyFallbackSupported()); } - /** Tests when {@link ConfigurationInternal#getGeoDetectionRunInBackgroundEnabled()} is true. */ + /** + * Tests when {@link ConfigurationInternal#getGeoDetectionRunInBackgroundEnabledSetting()} + * is true. + */ @Test public void test_geoDetectionRunInBackgroundEnabled() { ConfigurationInternal baseConfig = new ConfigurationInternal.Builder() diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java index ea801e887c4c..8207c1915edb 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/MetricsTimeZoneDetectorStateTest.java @@ -158,7 +158,7 @@ public class MetricsTimeZoneDetectorStateTest { metricsTimeZoneDetectorState.isGeoDetectionSupported()); assertEquals(configurationInternal.isTelephonyFallbackSupported(), metricsTimeZoneDetectorState.isTelephonyTimeZoneFallbackSupported()); - assertEquals(configurationInternal.getGeoDetectionRunInBackgroundEnabled(), + assertEquals(configurationInternal.getGeoDetectionRunInBackgroundEnabledSetting(), metricsTimeZoneDetectorState.getGeoDetectionRunInBackgroundEnabled()); assertEquals(configurationInternal.isEnhancedMetricsCollectionEnabled(), metricsTimeZoneDetectorState.isEnhancedMetricsCollectionEnabled()); |