diff options
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()); |