Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74f2b77d authored by Neil Fuller's avatar Neil Fuller Committed by Android (Google) Code Review
Browse files

Merge "Add location-based tz detection in the background"

parents cbd4650e 5a020246
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ public final class ServerFlags {
     */
    @StringDef(prefix = "KEY_", value = {
            KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED,
            KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED,
            KEY_PRIMARY_LTZP_MODE_OVERRIDE,
            KEY_SECONDARY_LTZP_MODE_OVERRIDE,
            KEY_LTZP_INITIALIZATION_TIMEOUT_FUZZ_MILLIS,
@@ -81,6 +82,15 @@ public final class ServerFlags {
    public static final @DeviceConfigKey String KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED =
            "location_time_zone_detection_feature_supported";

    /**
     * Controls whether location time zone detection should run all the time on supported devices,
     * even when the user has not enabled it explicitly in settings. Enabled for internal testing
     * only.
     */
    public static final @DeviceConfigKey String
            KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED =
            "location_time_zone_detection_run_in_background_enabled";

    /**
     * The key for the server flag that can override the device config for whether the primary
     * location time zone provider is enabled, disabled, or (for testing) in simulation mode.
+69 −8
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED;
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.time.TimeZoneCapabilities;
@@ -28,6 +29,10 @@ import android.app.time.TimeZoneCapabilitiesAndConfig;
import android.app.time.TimeZoneConfiguration;
import android.os.UserHandle;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Objects;

/**
@@ -37,9 +42,23 @@ import java.util.Objects;
 */
public final class ConfigurationInternal {

    @IntDef(prefix = "DETECTION_MODE_",
            value = { DETECTION_MODE_UNKNOWN, DETECTION_MODE_MANUAL, DETECTION_MODE_GEO,
                    DETECTION_MODE_TELEPHONY }
    )
    @Retention(RetentionPolicy.SOURCE)
    @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
    @interface DetectionMode {};

    public static final @DetectionMode int DETECTION_MODE_UNKNOWN = 0;
    public static final @DetectionMode int DETECTION_MODE_MANUAL = 1;
    public static final @DetectionMode int DETECTION_MODE_GEO = 2;
    public static final @DetectionMode int DETECTION_MODE_TELEPHONY = 3;

    private final boolean mTelephonyDetectionSupported;
    private final boolean mGeoDetectionSupported;
    private final boolean mTelephonyFallbackSupported;
    private final boolean mGeoDetectionRunInBackgroundEnabled;
    private final boolean mEnhancedMetricsCollectionEnabled;
    private final boolean mAutoDetectionEnabledSetting;
    private final @UserIdInt int mUserId;
@@ -51,6 +70,7 @@ public final class ConfigurationInternal {
        mTelephonyDetectionSupported = builder.mTelephonyDetectionSupported;
        mGeoDetectionSupported = builder.mGeoDetectionSupported;
        mTelephonyFallbackSupported = builder.mTelephonyFallbackSupported;
        mGeoDetectionRunInBackgroundEnabled = builder.mGeoDetectionRunInBackgroundEnabled;
        mEnhancedMetricsCollectionEnabled = builder.mEnhancedMetricsCollectionEnabled;
        mAutoDetectionEnabledSetting = builder.mAutoDetectionEnabledSetting;

@@ -83,6 +103,16 @@ public final class ConfigurationInternal {
        return mTelephonyFallbackSupported;
    }

    /**
     * Returns {@code true} if location time zone detection should run all the time on supported
     * devices, even when the user has not enabled it explicitly in settings. Enabled for internal
     * testing only. See {@link #isGeoDetectionExecutionEnabled()} and {@link #getDetectionMode()}
     * for details.
     */
    boolean getGeoDetectionRunInBackgroundEnabled() {
        return mGeoDetectionRunInBackgroundEnabled;
    }

    /**
     * Returns {@code true} if the device can collect / report extra metrics information for QA
     * / testers. These metrics might involve logging more expensive or more revealing data that
@@ -132,14 +162,31 @@ public final class ConfigurationInternal {
    }

    /**
     * Returns true if geolocation time zone detection behavior is actually enabled, which can be
     * distinct from the raw setting value.
     * Returns the detection mode to use, i.e. which suggestions to use to determine the device's
     * time zone.
     */
    public boolean getGeoDetectionEnabledBehavior() {
        return getAutoDetectionEnabledBehavior()
                && isGeoDetectionSupported()
    public @DetectionMode int getDetectionMode() {
        if (!getAutoDetectionEnabledBehavior()) {
            return DETECTION_MODE_MANUAL;
        } else if (isGeoDetectionSupported() && getLocationEnabledSetting()
                && getGeoDetectionEnabledSetting()) {
            return DETECTION_MODE_GEO;
        } else {
            return DETECTION_MODE_TELEPHONY;
        }
    }

    /**
     * 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()}.
     */
    public boolean isGeoDetectionExecutionEnabled() {
        return isGeoDetectionSupported()
                && getLocationEnabledSetting()
                && getGeoDetectionEnabledSetting();
                && ((mAutoDetectionEnabledSetting && getGeoDetectionEnabledSetting())
                || getGeoDetectionRunInBackgroundEnabled());
    }

    /** Creates a {@link TimeZoneCapabilitiesAndConfig} object using the configuration values. */
@@ -238,6 +285,7 @@ public final class ConfigurationInternal {
                && mTelephonyDetectionSupported == that.mTelephonyDetectionSupported
                && mGeoDetectionSupported == that.mGeoDetectionSupported
                && mTelephonyFallbackSupported == that.mTelephonyFallbackSupported
                && mGeoDetectionRunInBackgroundEnabled == that.mGeoDetectionRunInBackgroundEnabled
                && mEnhancedMetricsCollectionEnabled == that.mEnhancedMetricsCollectionEnabled
                && mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting
                && mLocationEnabledSetting == that.mLocationEnabledSetting
@@ -248,8 +296,8 @@ public final class ConfigurationInternal {
    public int hashCode() {
        return Objects.hash(mUserId, mUserConfigAllowed, mTelephonyDetectionSupported,
                mGeoDetectionSupported, mTelephonyFallbackSupported,
                mEnhancedMetricsCollectionEnabled, mAutoDetectionEnabledSetting,
                mLocationEnabledSetting, mGeoDetectionEnabledSetting);
                mGeoDetectionRunInBackgroundEnabled, mEnhancedMetricsCollectionEnabled,
                mAutoDetectionEnabledSetting, mLocationEnabledSetting, mGeoDetectionEnabledSetting);
    }

    @Override
@@ -260,6 +308,7 @@ public final class ConfigurationInternal {
                + ", mTelephonyDetectionSupported=" + mTelephonyDetectionSupported
                + ", mGeoDetectionSupported=" + mGeoDetectionSupported
                + ", mTelephonyFallbackSupported=" + mTelephonyFallbackSupported
                + ", mGeoDetectionRunInBackgroundEnabled=" + mGeoDetectionRunInBackgroundEnabled
                + ", mEnhancedMetricsCollectionEnabled=" + mEnhancedMetricsCollectionEnabled
                + ", mAutoDetectionEnabledSetting=" + mAutoDetectionEnabledSetting
                + ", mLocationEnabledSetting=" + mLocationEnabledSetting
@@ -278,6 +327,7 @@ public final class ConfigurationInternal {
        private boolean mTelephonyDetectionSupported;
        private boolean mGeoDetectionSupported;
        private boolean mTelephonyFallbackSupported;
        private boolean mGeoDetectionRunInBackgroundEnabled;
        private boolean mEnhancedMetricsCollectionEnabled;
        private boolean mAutoDetectionEnabledSetting;
        private boolean mLocationEnabledSetting;
@@ -299,6 +349,7 @@ public final class ConfigurationInternal {
            this.mTelephonyDetectionSupported = toCopy.mTelephonyDetectionSupported;
            this.mTelephonyFallbackSupported = toCopy.mTelephonyFallbackSupported;
            this.mGeoDetectionSupported = toCopy.mGeoDetectionSupported;
            this.mGeoDetectionRunInBackgroundEnabled = toCopy.mGeoDetectionRunInBackgroundEnabled;
            this.mEnhancedMetricsCollectionEnabled = toCopy.mEnhancedMetricsCollectionEnabled;
            this.mAutoDetectionEnabledSetting = toCopy.mAutoDetectionEnabledSetting;
            this.mLocationEnabledSetting = toCopy.mLocationEnabledSetting;
@@ -338,6 +389,16 @@ public final class ConfigurationInternal {
            return this;
        }

        /**
         * Sets whether location time zone detection should run all the time on supported devices,
         * even when the user has not enabled it explicitly in settings. Enabled for internal
         * testing only.
         */
        public Builder setGeoDetectionRunInBackgroundEnabled(boolean enabled) {
            mGeoDetectionRunInBackgroundEnabled = enabled;
            return this;
        }

        /**
         * Sets the value for enhanced metrics collection.
         */
+25 −10
Original line number Diff line number Diff line
@@ -45,14 +45,17 @@ import java.util.Objects;
public final class MetricsTimeZoneDetectorState {

    @IntDef(prefix = "DETECTION_MODE_",
            value = { DETECTION_MODE_MANUAL, DETECTION_MODE_GEO, DETECTION_MODE_TELEPHONY})
            value = { DETECTION_MODE_UNKNOWN, DETECTION_MODE_MANUAL, DETECTION_MODE_GEO,
                    DETECTION_MODE_TELEPHONY }
    )
    @Retention(RetentionPolicy.SOURCE)
    @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
    public @interface DetectionMode {};

    public static final @DetectionMode int DETECTION_MODE_MANUAL = 0;
    public static final @DetectionMode int DETECTION_MODE_GEO = 1;
    public static final @DetectionMode int DETECTION_MODE_TELEPHONY = 2;
    public static final @DetectionMode int DETECTION_MODE_UNKNOWN = 0;
    public static final @DetectionMode int DETECTION_MODE_MANUAL = 1;
    public static final @DetectionMode int DETECTION_MODE_GEO = 2;
    public static final @DetectionMode int DETECTION_MODE_TELEPHONY = 3;

    @NonNull private final ConfigurationInternal mConfigurationInternal;
    private final int mDeviceTimeZoneIdOrdinal;
@@ -123,6 +126,15 @@ public final class MetricsTimeZoneDetectorState {
        return mConfigurationInternal.isTelephonyFallbackSupported();
    }

    /**
     * Returns {@code true} if location time zone detection should run all the time on supported
     * devices, even when the user has not enabled it explicitly in settings. Enabled for internal
     * testing only.
     */
    public boolean getGeoDetectionRunInBackgroundEnabled() {
        return mConfigurationInternal.getGeoDetectionRunInBackgroundEnabled();
    }

    /** Returns true if enhanced metric collection is enabled. */
    public boolean isEnhancedMetricsCollectionEnabled() {
        return mConfigurationInternal.isEnhancedMetricsCollectionEnabled();
@@ -148,12 +160,15 @@ public final class MetricsTimeZoneDetectorState {
     * things besides the user's setting.
     */
    public @DetectionMode int getDetectionMode() {
        if (!mConfigurationInternal.getAutoDetectionEnabledBehavior()) {
        switch (mConfigurationInternal.getDetectionMode()) {
            case ConfigurationInternal.DETECTION_MODE_MANUAL:
                return DETECTION_MODE_MANUAL;
        } else if (mConfigurationInternal.getGeoDetectionEnabledBehavior()) {
            case ConfigurationInternal.DETECTION_MODE_GEO:
                return DETECTION_MODE_GEO;
        } else {
            case ConfigurationInternal.DETECTION_MODE_TELEPHONY:
                return DETECTION_MODE_TELEPHONY;
            default:
                return DETECTION_MODE_UNKNOWN;
        }
    }

+15 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
    private static final Set<String> CONFIGURATION_INTERNAL_SERVER_FLAGS_KEYS_TO_WATCH =
            Collections.unmodifiableSet(new ArraySet<>(new String[] {
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED,
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED,
                    ServerFlags.KEY_ENHANCED_METRICS_COLLECTION_ENABLED,
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE,
@@ -75,6 +76,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
    private static final Set<String> LOCATION_TIME_ZONE_MANAGER_SERVER_FLAGS_KEYS_TO_WATCH =
            Collections.unmodifiableSet(new ArraySet<>(new String[] {
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED,
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED,
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT,
                    ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE,
                    ServerFlags.KEY_PRIMARY_LTZP_MODE_OVERRIDE,
@@ -297,6 +299,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
                        isTelephonyTimeZoneDetectionFeatureSupported())
                .setGeoDetectionFeatureSupported(isGeoTimeZoneDetectionFeatureSupported())
                .setTelephonyFallbackSupported(isTelephonyFallbackSupported())
                .setGeoDetectionRunInBackgroundEnabled(getGeoDetectionRunInBackgroundEnabled())
                .setEnhancedMetricsCollectionEnabled(isEnhancedMetricsCollectionEnabled())
                .setAutoDetectionEnabledSetting(getAutoDetectionEnabledSetting())
                .setUserConfigAllowed(isUserConfigAllowed(userId))
@@ -402,6 +405,18 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
                defaultEnabled);
    }

    /**
     * Returns {@code true} if location time zone detection should run all the time on supported
     * devices, even when the user has not enabled it explicitly in settings. Enabled for internal
     * testing only.
     */
    private boolean getGeoDetectionRunInBackgroundEnabled() {
        final boolean defaultEnabled = false;
        return mServerFlags.getBoolean(
                ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED,
                defaultEnabled);
    }

    /**
     * Returns {@code true} if extra metrics / telemetry information can be collected. Used for
     * internal testers.
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.provider.DeviceConfig.NAMESPACE_SYSTEM_TIME;

import static com.android.server.timedetector.ServerFlags.KEY_ENHANCED_METRICS_COLLECTION_ENABLED;
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_FEATURE_SUPPORTED;
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED;
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT;
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE;
import static com.android.server.timedetector.ServerFlags.KEY_TIME_ZONE_DETECTOR_TELEPHONY_FALLBACK_SUPPORTED;
@@ -237,6 +238,9 @@ class TimeZoneDetectorShellCommand extends ShellCommand {
        pw.printf("    Only observed if the geolocation time zone detection feature is enabled in"
                + " config.\n");
        pw.printf("    Set this to false to disable the feature.\n");
        pw.printf("  %s\n", KEY_LOCATION_TIME_ZONE_DETECTION_RUN_IN_BACKGROUND_ENABLED);
        pw.printf("    Runs geolocation time zone detection even when it not enabled by the user."
                + " The result is not used to set the device's time zone [*]\n");
        pw.printf("  %s\n", KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_DEFAULT);
        pw.printf("    Only used if the device does not have an explicit 'geolocation time zone"
                + " detection enabled' setting stored [*].\n");
Loading