diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 89b768d7dff70..5137bc14339ff 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11849,7 +11849,13 @@ public final class Settings { /** * Value to specify if the device's UTC system clock should be set automatically, e.g. using - * telephony signals like NITZ, or other sources like GNSS or NTP. 1=yes, 0=no (manual) + * telephony signals like NITZ, or other sources like GNSS or NTP. + * + *
Prefer {@link android.app.time.TimeManager} API calls to determine the state of + * automatic time detection instead of directly observing this setting as it may be ignored + * by the time_detector service under various conditions. + * + *
1=yes, 0=no (manual) */ @Readable public static final String AUTO_TIME = "auto_time"; @@ -11857,11 +11863,34 @@ public final class Settings { /** * Value to specify if the device's time zone system property should be set automatically, * e.g. using telephony signals like MCC and NITZ, or other mechanisms like the location. - * 1=yes, 0=no (manual). + * + *
Prefer {@link android.app.time.TimeManager} API calls to determine the state of + * automatic time zone detection instead of directly observing this setting as it may be + * ignored by the time_zone_detector service under various conditions. + * + *
1=yes, 0=no (manual). */ @Readable public static final String AUTO_TIME_ZONE = "auto_time_zone"; + /** + * Records whether an explicit preference for {@link #AUTO_TIME_ZONE} has been expressed + * instead of the current value being the default. This value is used to tell if the {@link + * #AUTO_TIME_ZONE} value can be influenced by experiment flags that alter the setting's + * value for internal testers: once the user indicates a preference they leave the + * experiment, only users that are still using the default will be affected by the flag. + * + *
Since {@link #AUTO_TIME_ZONE} can be altered by components besides the system server, + * and not just via the time_zone_detector logic that sets this value, this isn't guaranteed + * to be set when the device diverges from the default in all cases. Important AOSP system + * components like SettingsUI do use the time_zone_detector APIs. + * + *
1="has been set explicitly"
+ *
+ * @hide
+ */
+ public static final String AUTO_TIME_ZONE_EXPLICIT = "auto_time_zone_explicit";
+
/**
* URI for the car dock "in" event sound.
* @hide
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index e0e37200219ca..a9d14641af9a4 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -137,6 +137,7 @@ public class SettingsBackupTest {
Settings.Global.AUTOFILL_LOGGING_LEVEL,
Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
+ Settings.Global.AUTO_TIME_ZONE_EXPLICIT,
Settings.Global.AVERAGE_TIME_TO_DISCHARGE,
Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
diff --git a/services/core/java/com/android/server/timedetector/ServerFlags.java b/services/core/java/com/android/server/timedetector/ServerFlags.java
index 28d34c26e0ddf..2049a0288f5a4 100644
--- a/services/core/java/com/android/server/timedetector/ServerFlags.java
+++ b/services/core/java/com/android/server/timedetector/ServerFlags.java
@@ -69,6 +69,7 @@ public final class ServerFlags {
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE,
KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE,
+ KEY_TIME_ZONE_DETECTOR_AUTO_DETECTION_ENABLED_DEFAULT,
KEY_TIME_ZONE_DETECTOR_TELEPHONY_FALLBACK_SUPPORTED,
KEY_ENHANCED_METRICS_COLLECTION_ENABLED,
})
@@ -153,6 +154,14 @@ public final class ServerFlags {
KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT =
"location_time_zone_detection_setting_enabled_default";
+ /**
+ * The key to alter a device's "automatic time zone detection enabled" setting default value.
+ * This flag is only intended for internal testing.
+ */
+ public static final @DeviceConfigKey String
+ KEY_TIME_ZONE_DETECTOR_AUTO_DETECTION_ENABLED_DEFAULT =
+ "time_zone_detector_auto_detection_enabled_default";
+
/**
* The key to control support for time zone detection falling back to telephony detection under
* certain circumstances.
diff --git a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
index 6ebaf14c28dbe..a71f9c7f90863 100644
--- a/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/ServiceConfigAccessorImpl.java
@@ -64,6 +64,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
ServerFlags.KEY_ENHANCED_METRICS_COLLECTION_ENABLED,
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE,
+ ServerFlags.KEY_TIME_ZONE_DETECTOR_AUTO_DETECTION_ENABLED_DEFAULT,
ServerFlags.KEY_TIME_ZONE_DETECTOR_TELEPHONY_FALLBACK_SUPPORTED
);
@@ -174,7 +175,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
}
}, filter, null, null /* main thread */);
- // Add async callbacks for global settings being changed.
+ // Add async callbacks for changes to global settings that influence behavior.
ContentResolver contentResolver = mContext.getContentResolver();
ContentObserver contentObserver = new ContentObserver(mContext.getMainThreadHandler()) {
@Override
@@ -184,6 +185,9 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
};
contentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true, contentObserver);
+ contentResolver.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE_EXPLICIT), true,
+ contentObserver);
// Add async callbacks for user scoped location settings being changed.
contentResolver.registerContentObserver(
@@ -239,8 +243,9 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
@Override
public synchronized boolean updateConfiguration(@UserIdInt int userId,
- @NonNull TimeZoneConfiguration requestedConfiguration, boolean bypassUserPolicyChecks) {
- Objects.requireNonNull(requestedConfiguration);
+ @NonNull TimeZoneConfiguration requestedConfigurationUpdates,
+ boolean bypassUserPolicyChecks) {
+ Objects.requireNonNull(requestedConfigurationUpdates);
ConfigurationInternal configurationInternal = getConfigurationInternal(userId);
TimeZoneCapabilities capabilities =
@@ -248,7 +253,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
TimeZoneConfiguration oldConfiguration = configurationInternal.asConfiguration();
final TimeZoneConfiguration newConfiguration =
- capabilities.tryApplyConfigChanges(oldConfiguration, requestedConfiguration);
+ capabilities.tryApplyConfigChanges(oldConfiguration, requestedConfigurationUpdates);
if (newConfiguration == null) {
// The changes could not be made because the user's capabilities do not allow it.
return false;
@@ -256,7 +261,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
// Store the configuration / notify as needed. This will cause the mEnvironment to invoke
// handleConfigChanged() asynchronously.
- storeConfiguration(userId, newConfiguration);
+ storeConfiguration(userId, requestedConfigurationUpdates, newConfiguration);
return true;
}
@@ -268,15 +273,20 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
*/
@GuardedBy("this")
private void storeConfiguration(@UserIdInt int userId,
- @NonNull TimeZoneConfiguration configuration) {
- Objects.requireNonNull(configuration);
+ @NonNull TimeZoneConfiguration requestedConfigurationUpdates,
+ @NonNull TimeZoneConfiguration newConfiguration) {
+ Objects.requireNonNull(newConfiguration);
// Avoid writing the auto detection enabled setting for devices that do not support auto
// 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 support new types of auto detection on the same hardware.
if (isAutoDetectionFeatureSupported()) {
- final boolean autoDetectionEnabled = configuration.isAutoDetectionEnabled();
+ if (requestedConfigurationUpdates.hasIsAutoDetectionEnabled()) {
+ // Record that the auto detection enabled setting has now been set explicitly.
+ Settings.Global.putInt(mCr, Settings.Global.AUTO_TIME_ZONE_EXPLICIT, 1);
+ }
+ final boolean autoDetectionEnabled = newConfiguration.isAutoDetectionEnabled();
setAutoDetectionEnabledIfRequired(autoDetectionEnabled);
// Only write the geo detection enabled setting when its values is used, e.g.:
@@ -288,10 +298,10 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
// 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()
+ if (getGeoDetectionSettingEnabledOverride().isEmpty()
&& isGeoTimeZoneDetectionFeatureSupported()
&& isTelephonyTimeZoneDetectionFeatureSupported()) {
- final boolean geoDetectionEnabledSetting = configuration.isGeoDetectionEnabled();
+ final boolean geoDetectionEnabledSetting = newConfiguration.isGeoDetectionEnabled();
setGeoDetectionEnabledSettingIfRequired(userId, geoDetectionEnabledSetting);
}
}
@@ -335,7 +345,31 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
}
private boolean getAutoDetectionEnabledSetting() {
- return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME_ZONE, 1 /* default */) > 0;
+ boolean autoDetectionEnabledSetting =
+ Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME_ZONE, 1 /* default */) > 0;
+
+ Optional