Merge "Add "enhanced metrics collection" support"
This commit is contained in:
@@ -102,6 +102,14 @@ public interface TimeZoneDetector {
|
||||
*/
|
||||
String SHELL_COMMAND_ENABLE_TELEPHONY_FALLBACK = "enable_telephony_fallback";
|
||||
|
||||
/**
|
||||
* A shell command that dumps a {@link
|
||||
* com.android.server.timezonedetector.MetricsTimeZoneDetectorState} object to stdout for
|
||||
* debugging.
|
||||
* @hide
|
||||
*/
|
||||
String SHELL_COMMAND_DUMP_METRICS = "dump_metrics";
|
||||
|
||||
/**
|
||||
* A shared utility method to create a {@link ManualTimeZoneSuggestion}.
|
||||
*
|
||||
|
||||
@@ -32,16 +32,8 @@ message GeolocationTimeZoneSuggestionProto {
|
||||
}
|
||||
|
||||
/*
|
||||
* An obfuscated and simplified time zone suggestion for metrics use.
|
||||
*
|
||||
* The suggestion's time zone IDs (which relate to location) are obfuscated by
|
||||
* mapping them to an ordinal. When the ordinal is assigned consistently across
|
||||
* several objects (i.e. so the same time zone ID is always mapped to the same
|
||||
* ordinal), this allows comparisons between those objects. For example, we can
|
||||
* answer "did these two suggestions agree?", "does the suggestion match the
|
||||
* device's current time zone?", without leaking knowledge of location. Ordinals
|
||||
* are also significantly more compact than full IANA TZDB IDs, albeit highly
|
||||
* unstable and of limited use.
|
||||
* A generic-form time zone suggestion for metrics use. Required to be a superset of the
|
||||
* MetricsTimeZoneSuggestion proto defined in atoms.proto to ensure binary compatibility.
|
||||
*/
|
||||
message MetricsTimeZoneSuggestion {
|
||||
option (android.msg_privacy).dest = DEST_AUTOMATIC;
|
||||
@@ -55,5 +47,24 @@ message MetricsTimeZoneSuggestion {
|
||||
// The ordinals for time zone(s) in the suggestion. Always empty for
|
||||
// UNCERTAIN, and can be empty for CERTAIN, for example when the device is in
|
||||
// a disputed area / on an ocean.
|
||||
repeated uint32 time_zone_ordinals = 2;
|
||||
//
|
||||
// The suggestion's time zone IDs (which relate to location) are obfuscated by
|
||||
// mapping them to an ordinal. When the ordinal is assigned consistently across
|
||||
// several objects (i.e. so the same time zone ID is always mapped to the same
|
||||
// ordinal), this allows comparisons between those objects. For example, we can
|
||||
// answer "did these two suggestions agree?", "does the suggestion match the
|
||||
// device's current time zone?", without leaking knowledge of location. Ordinals
|
||||
// are also significantly more compact than full IANA TZDB IDs, albeit unstable
|
||||
// and of limited use.
|
||||
repeated int32 time_zone_ordinals = 2;
|
||||
|
||||
// The actual time zone ID(s) in the suggestion. Similar to time_zone_ordinals
|
||||
// but contains the actual string IDs.
|
||||
//
|
||||
// This information is only captured / reported for some devices based on the
|
||||
// value of a server side flag, i.e. it could be enabled for internal testers.
|
||||
// Therefore the list can be empty even when time_zone_ordinals is populated.
|
||||
//
|
||||
// When enabled, see time_zone_ordinals for the expected number of values.
|
||||
repeated string time_zone_ids = 3;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ public final class ServerFlags {
|
||||
KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE,
|
||||
KEY_TIME_DETECTOR_ORIGIN_PRIORITIES_OVERRIDE,
|
||||
KEY_TIME_ZONE_DETECTOR_TELEPHONY_FALLBACK_SUPPORTED,
|
||||
KEY_ENHANCED_METRICS_COLLECTION_ENABLED,
|
||||
})
|
||||
@Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@@ -156,12 +157,18 @@ public final class ServerFlags {
|
||||
"time_detector_origin_priorities_override";
|
||||
|
||||
/**
|
||||
* The key to override the time detector lower bound configuration. The values is the number of
|
||||
* The key to override the time detector lower bound configuration. The value is the number of
|
||||
* milliseconds since the beginning of the Unix epoch.
|
||||
*/
|
||||
public static final @DeviceConfigKey String KEY_TIME_DETECTOR_LOWER_BOUND_MILLIS_OVERRIDE =
|
||||
"time_detector_lower_bound_millis_override";
|
||||
|
||||
/**
|
||||
* The key to allow extra metrics / telemetry information to be collected from internal testers.
|
||||
*/
|
||||
public static final @DeviceConfigKey String KEY_ENHANCED_METRICS_COLLECTION_ENABLED =
|
||||
"enhanced_metrics_collection_enabled";
|
||||
|
||||
@GuardedBy("mListeners")
|
||||
private final ArrayMap<ConfigurationChangeListener, Set<String>> mListeners = new ArrayMap<>();
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ public final class ConfigurationInternal {
|
||||
private final boolean mTelephonyDetectionSupported;
|
||||
private final boolean mGeoDetectionSupported;
|
||||
private final boolean mTelephonyFallbackSupported;
|
||||
private final boolean mEnhancedMetricsCollectionEnabled;
|
||||
private final boolean mAutoDetectionEnabledSetting;
|
||||
private final @UserIdInt int mUserId;
|
||||
private final boolean mUserConfigAllowed;
|
||||
@@ -50,6 +51,7 @@ public final class ConfigurationInternal {
|
||||
mTelephonyDetectionSupported = builder.mTelephonyDetectionSupported;
|
||||
mGeoDetectionSupported = builder.mGeoDetectionSupported;
|
||||
mTelephonyFallbackSupported = builder.mTelephonyFallbackSupported;
|
||||
mEnhancedMetricsCollectionEnabled = builder.mEnhancedMetricsCollectionEnabled;
|
||||
mAutoDetectionEnabledSetting = builder.mAutoDetectionEnabledSetting;
|
||||
|
||||
mUserId = builder.mUserId;
|
||||
@@ -81,6 +83,15 @@ public final class ConfigurationInternal {
|
||||
return mTelephonyFallbackSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* would not be collected from the set of public users.
|
||||
*/
|
||||
public boolean isEnhancedMetricsCollectionEnabled() {
|
||||
return mEnhancedMetricsCollectionEnabled;
|
||||
}
|
||||
|
||||
/** Returns the value of the auto time zone detection enabled setting. */
|
||||
public boolean getAutoDetectionEnabledSetting() {
|
||||
return mAutoDetectionEnabledSetting;
|
||||
@@ -227,6 +238,7 @@ public final class ConfigurationInternal {
|
||||
&& mTelephonyDetectionSupported == that.mTelephonyDetectionSupported
|
||||
&& mGeoDetectionSupported == that.mGeoDetectionSupported
|
||||
&& mTelephonyFallbackSupported == that.mTelephonyFallbackSupported
|
||||
&& mEnhancedMetricsCollectionEnabled == that.mEnhancedMetricsCollectionEnabled
|
||||
&& mAutoDetectionEnabledSetting == that.mAutoDetectionEnabledSetting
|
||||
&& mLocationEnabledSetting == that.mLocationEnabledSetting
|
||||
&& mGeoDetectionEnabledSetting == that.mGeoDetectionEnabledSetting;
|
||||
@@ -235,7 +247,8 @@ public final class ConfigurationInternal {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mUserId, mUserConfigAllowed, mTelephonyDetectionSupported,
|
||||
mGeoDetectionSupported, mTelephonyFallbackSupported, mAutoDetectionEnabledSetting,
|
||||
mGeoDetectionSupported, mTelephonyFallbackSupported,
|
||||
mEnhancedMetricsCollectionEnabled, mAutoDetectionEnabledSetting,
|
||||
mLocationEnabledSetting, mGeoDetectionEnabledSetting);
|
||||
}
|
||||
|
||||
@@ -247,6 +260,7 @@ public final class ConfigurationInternal {
|
||||
+ ", mTelephonyDetectionSupported=" + mTelephonyDetectionSupported
|
||||
+ ", mGeoDetectionSupported=" + mGeoDetectionSupported
|
||||
+ ", mTelephonyFallbackSupported=" + mTelephonyFallbackSupported
|
||||
+ ", mEnhancedMetricsCollectionEnabled=" + mEnhancedMetricsCollectionEnabled
|
||||
+ ", mAutoDetectionEnabledSetting=" + mAutoDetectionEnabledSetting
|
||||
+ ", mLocationEnabledSetting=" + mLocationEnabledSetting
|
||||
+ ", mGeoDetectionEnabledSetting=" + mGeoDetectionEnabledSetting
|
||||
@@ -264,6 +278,7 @@ public final class ConfigurationInternal {
|
||||
private boolean mTelephonyDetectionSupported;
|
||||
private boolean mGeoDetectionSupported;
|
||||
private boolean mTelephonyFallbackSupported;
|
||||
private boolean mEnhancedMetricsCollectionEnabled;
|
||||
private boolean mAutoDetectionEnabledSetting;
|
||||
private boolean mLocationEnabledSetting;
|
||||
private boolean mGeoDetectionEnabledSetting;
|
||||
@@ -284,6 +299,7 @@ public final class ConfigurationInternal {
|
||||
this.mTelephonyDetectionSupported = toCopy.mTelephonyDetectionSupported;
|
||||
this.mTelephonyFallbackSupported = toCopy.mTelephonyFallbackSupported;
|
||||
this.mGeoDetectionSupported = toCopy.mGeoDetectionSupported;
|
||||
this.mEnhancedMetricsCollectionEnabled = toCopy.mEnhancedMetricsCollectionEnabled;
|
||||
this.mAutoDetectionEnabledSetting = toCopy.mAutoDetectionEnabledSetting;
|
||||
this.mLocationEnabledSetting = toCopy.mLocationEnabledSetting;
|
||||
this.mGeoDetectionEnabledSetting = toCopy.mGeoDetectionEnabledSetting;
|
||||
@@ -322,6 +338,14 @@ public final class ConfigurationInternal {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for enhanced metrics collection.
|
||||
*/
|
||||
public Builder setEnhancedMetricsCollectionEnabled(boolean enabled) {
|
||||
mEnhancedMetricsCollectionEnabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the automatic time zone detection enabled setting for this device.
|
||||
*/
|
||||
|
||||
@@ -34,11 +34,13 @@ import java.util.Objects;
|
||||
* A class that provides time zone detector state information for metrics.
|
||||
*
|
||||
* <p>
|
||||
* Regarding time zone ID ordinals:
|
||||
* Regarding the use of time zone ID ordinals in metrics / telemetry:
|
||||
* <p>
|
||||
* We don't want to leak user location information by reporting time zone IDs. Instead, time zone
|
||||
* IDs are consistently identified within a given instance of this class by a numeric ID. This
|
||||
* allows comparison of IDs without revealing what those IDs are.
|
||||
* For general metrics, we don't want to leak user location information by reporting time zone
|
||||
* IDs. Instead, time zone IDs are consistently identified within a given instance of this class by
|
||||
* a numeric ID (ordinal). This allows comparison of IDs without revealing what those IDs are.
|
||||
* See {@link #isEnhancedMetricsCollectionEnabled()} for the setting that enables actual IDs to be
|
||||
* collected.
|
||||
*/
|
||||
public final class MetricsTimeZoneDetectorState {
|
||||
|
||||
@@ -54,6 +56,7 @@ public final class MetricsTimeZoneDetectorState {
|
||||
|
||||
@NonNull private final ConfigurationInternal mConfigurationInternal;
|
||||
private final int mDeviceTimeZoneIdOrdinal;
|
||||
@Nullable private final String mDeviceTimeZoneId;
|
||||
@Nullable private final MetricsTimeZoneSuggestion mLatestManualSuggestion;
|
||||
@Nullable private final MetricsTimeZoneSuggestion mLatestTelephonySuggestion;
|
||||
@Nullable private final MetricsTimeZoneSuggestion mLatestGeolocationSuggestion;
|
||||
@@ -61,11 +64,13 @@ public final class MetricsTimeZoneDetectorState {
|
||||
private MetricsTimeZoneDetectorState(
|
||||
@NonNull ConfigurationInternal configurationInternal,
|
||||
int deviceTimeZoneIdOrdinal,
|
||||
@Nullable String deviceTimeZoneId,
|
||||
@Nullable MetricsTimeZoneSuggestion latestManualSuggestion,
|
||||
@Nullable MetricsTimeZoneSuggestion latestTelephonySuggestion,
|
||||
@Nullable MetricsTimeZoneSuggestion latestGeolocationSuggestion) {
|
||||
mConfigurationInternal = Objects.requireNonNull(configurationInternal);
|
||||
mDeviceTimeZoneIdOrdinal = deviceTimeZoneIdOrdinal;
|
||||
mDeviceTimeZoneId = deviceTimeZoneId;
|
||||
mLatestManualSuggestion = latestManualSuggestion;
|
||||
mLatestTelephonySuggestion = latestTelephonySuggestion;
|
||||
mLatestGeolocationSuggestion = latestGeolocationSuggestion;
|
||||
@@ -83,18 +88,24 @@ public final class MetricsTimeZoneDetectorState {
|
||||
@Nullable TelephonyTimeZoneSuggestion latestTelephonySuggestion,
|
||||
@Nullable GeolocationTimeZoneSuggestion latestGeolocationSuggestion) {
|
||||
|
||||
boolean includeZoneIds = configurationInternal.isEnhancedMetricsCollectionEnabled();
|
||||
String metricDeviceTimeZoneId = includeZoneIds ? deviceTimeZoneId : null;
|
||||
int deviceTimeZoneIdOrdinal =
|
||||
tzIdOrdinalGenerator.ordinal(Objects.requireNonNull(deviceTimeZoneId));
|
||||
MetricsTimeZoneSuggestion latestCanonicalManualSuggestion =
|
||||
createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestManualSuggestion);
|
||||
createMetricsTimeZoneSuggestion(
|
||||
tzIdOrdinalGenerator, latestManualSuggestion, includeZoneIds);
|
||||
MetricsTimeZoneSuggestion latestCanonicalTelephonySuggestion =
|
||||
createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestTelephonySuggestion);
|
||||
createMetricsTimeZoneSuggestion(
|
||||
tzIdOrdinalGenerator, latestTelephonySuggestion, includeZoneIds);
|
||||
MetricsTimeZoneSuggestion latestCanonicalGeolocationSuggestion =
|
||||
createMetricsTimeZoneSuggestion(tzIdOrdinalGenerator, latestGeolocationSuggestion);
|
||||
createMetricsTimeZoneSuggestion(
|
||||
tzIdOrdinalGenerator, latestGeolocationSuggestion, includeZoneIds);
|
||||
|
||||
return new MetricsTimeZoneDetectorState(
|
||||
configurationInternal, deviceTimeZoneIdOrdinal, latestCanonicalManualSuggestion,
|
||||
latestCanonicalTelephonySuggestion, latestCanonicalGeolocationSuggestion);
|
||||
configurationInternal, deviceTimeZoneIdOrdinal, metricDeviceTimeZoneId,
|
||||
latestCanonicalManualSuggestion, latestCanonicalTelephonySuggestion,
|
||||
latestCanonicalGeolocationSuggestion);
|
||||
}
|
||||
|
||||
/** Returns true if the device supports telephony time zone detection. */
|
||||
@@ -112,6 +123,11 @@ public final class MetricsTimeZoneDetectorState {
|
||||
return mConfigurationInternal.isTelephonyFallbackSupported();
|
||||
}
|
||||
|
||||
/** Returns true if enhanced metric collection is enabled. */
|
||||
public boolean isEnhancedMetricsCollectionEnabled() {
|
||||
return mConfigurationInternal.isEnhancedMetricsCollectionEnabled();
|
||||
}
|
||||
|
||||
/** Returns true if user's location can be used generally. */
|
||||
public boolean getUserLocationEnabledSetting() {
|
||||
return mConfigurationInternal.getLocationEnabledSetting();
|
||||
@@ -142,13 +158,23 @@ public final class MetricsTimeZoneDetectorState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ordinal for the device's currently set time zone ID.
|
||||
* Returns the ordinal for the device's current time zone ID.
|
||||
* See {@link MetricsTimeZoneDetectorState} for information about ordinals.
|
||||
*/
|
||||
public int getDeviceTimeZoneIdOrdinal() {
|
||||
return mDeviceTimeZoneIdOrdinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device's current time zone ID. This will only be populated if {@link
|
||||
* #isEnhancedMetricsCollectionEnabled()} is {@code true}. See {@link
|
||||
* MetricsTimeZoneDetectorState} for details.
|
||||
*/
|
||||
@Nullable
|
||||
public String getDeviceTimeZoneId() {
|
||||
return mDeviceTimeZoneId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a canonical form of the last manual suggestion received.
|
||||
*/
|
||||
@@ -183,6 +209,7 @@ public final class MetricsTimeZoneDetectorState {
|
||||
}
|
||||
MetricsTimeZoneDetectorState that = (MetricsTimeZoneDetectorState) o;
|
||||
return mDeviceTimeZoneIdOrdinal == that.mDeviceTimeZoneIdOrdinal
|
||||
&& Objects.equals(mDeviceTimeZoneId, that.mDeviceTimeZoneId)
|
||||
&& mConfigurationInternal.equals(that.mConfigurationInternal)
|
||||
&& Objects.equals(mLatestManualSuggestion, that.mLatestManualSuggestion)
|
||||
&& Objects.equals(mLatestTelephonySuggestion, that.mLatestTelephonySuggestion)
|
||||
@@ -191,7 +218,7 @@ public final class MetricsTimeZoneDetectorState {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mConfigurationInternal, mDeviceTimeZoneIdOrdinal,
|
||||
return Objects.hash(mConfigurationInternal, mDeviceTimeZoneIdOrdinal, mDeviceTimeZoneId,
|
||||
mLatestManualSuggestion, mLatestTelephonySuggestion, mLatestGeolocationSuggestion);
|
||||
}
|
||||
|
||||
@@ -200,6 +227,7 @@ public final class MetricsTimeZoneDetectorState {
|
||||
return "MetricsTimeZoneDetectorState{"
|
||||
+ "mConfigurationInternal=" + mConfigurationInternal
|
||||
+ ", mDeviceTimeZoneIdOrdinal=" + mDeviceTimeZoneIdOrdinal
|
||||
+ ", mDeviceTimeZoneId=" + mDeviceTimeZoneId
|
||||
+ ", mLatestManualSuggestion=" + mLatestManualSuggestion
|
||||
+ ", mLatestTelephonySuggestion=" + mLatestTelephonySuggestion
|
||||
+ ", mLatestGeolocationSuggestion=" + mLatestGeolocationSuggestion
|
||||
@@ -209,34 +237,40 @@ public final class MetricsTimeZoneDetectorState {
|
||||
@Nullable
|
||||
private static MetricsTimeZoneSuggestion createMetricsTimeZoneSuggestion(
|
||||
@NonNull OrdinalGenerator<String> zoneIdOrdinalGenerator,
|
||||
@NonNull ManualTimeZoneSuggestion manualSuggestion) {
|
||||
@NonNull ManualTimeZoneSuggestion manualSuggestion,
|
||||
boolean includeFullZoneIds) {
|
||||
if (manualSuggestion == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int zoneIdOrdinal = zoneIdOrdinalGenerator.ordinal(manualSuggestion.getZoneId());
|
||||
return MetricsTimeZoneSuggestion.createCertain(
|
||||
new int[] { zoneIdOrdinal });
|
||||
String suggestionZoneId = manualSuggestion.getZoneId();
|
||||
String[] metricZoneIds = includeFullZoneIds ? new String[] { suggestionZoneId } : null;
|
||||
int[] zoneIdOrdinals = new int[] { zoneIdOrdinalGenerator.ordinal(suggestionZoneId) };
|
||||
return MetricsTimeZoneSuggestion.createCertain(metricZoneIds, zoneIdOrdinals);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static MetricsTimeZoneSuggestion createMetricsTimeZoneSuggestion(
|
||||
@NonNull OrdinalGenerator<String> zoneIdOrdinalGenerator,
|
||||
@NonNull TelephonyTimeZoneSuggestion telephonySuggestion) {
|
||||
@NonNull TelephonyTimeZoneSuggestion telephonySuggestion,
|
||||
boolean includeFullZoneIds) {
|
||||
if (telephonySuggestion == null) {
|
||||
return null;
|
||||
}
|
||||
if (telephonySuggestion.getZoneId() == null) {
|
||||
String suggestionZoneId = telephonySuggestion.getZoneId();
|
||||
if (suggestionZoneId == null) {
|
||||
return MetricsTimeZoneSuggestion.createUncertain();
|
||||
}
|
||||
int zoneIdOrdinal = zoneIdOrdinalGenerator.ordinal(telephonySuggestion.getZoneId());
|
||||
return MetricsTimeZoneSuggestion.createCertain(new int[] { zoneIdOrdinal });
|
||||
String[] metricZoneIds = includeFullZoneIds ? new String[] { suggestionZoneId } : null;
|
||||
int[] zoneIdOrdinals = new int[] { zoneIdOrdinalGenerator.ordinal(suggestionZoneId) };
|
||||
return MetricsTimeZoneSuggestion.createCertain(metricZoneIds, zoneIdOrdinals);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static MetricsTimeZoneSuggestion createMetricsTimeZoneSuggestion(
|
||||
@NonNull OrdinalGenerator<String> zoneIdOrdinalGenerator,
|
||||
@Nullable GeolocationTimeZoneSuggestion geolocationSuggestion) {
|
||||
@Nullable GeolocationTimeZoneSuggestion geolocationSuggestion,
|
||||
boolean includeFullZoneIds) {
|
||||
if (geolocationSuggestion == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -245,7 +279,9 @@ public final class MetricsTimeZoneDetectorState {
|
||||
if (zoneIds == null) {
|
||||
return MetricsTimeZoneSuggestion.createUncertain();
|
||||
}
|
||||
return MetricsTimeZoneSuggestion.createCertain(zoneIdOrdinalGenerator.ordinals(zoneIds));
|
||||
String[] metricZoneIds = includeFullZoneIds ? zoneIds.toArray(new String[0]) : null;
|
||||
int[] zoneIdOrdinals = zoneIdOrdinalGenerator.ordinals(zoneIds);
|
||||
return MetricsTimeZoneSuggestion.createCertain(metricZoneIds, zoneIdOrdinals);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,33 +290,49 @@ public final class MetricsTimeZoneDetectorState {
|
||||
* MetricsTimeZoneSuggestion proto definition.
|
||||
*/
|
||||
public static final class MetricsTimeZoneSuggestion {
|
||||
@Nullable
|
||||
private final int[] mZoneIdOrdinals;
|
||||
@Nullable private final String[] mZoneIds;
|
||||
@Nullable private final int[] mZoneIdOrdinals;
|
||||
|
||||
MetricsTimeZoneSuggestion(@Nullable int[] zoneIdOrdinals) {
|
||||
private MetricsTimeZoneSuggestion(
|
||||
@Nullable String[] zoneIds, @Nullable int[] zoneIdOrdinals) {
|
||||
mZoneIds = zoneIds;
|
||||
mZoneIdOrdinals = zoneIdOrdinals;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static MetricsTimeZoneSuggestion createUncertain() {
|
||||
return new MetricsTimeZoneSuggestion(null);
|
||||
return new MetricsTimeZoneSuggestion(null, null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static MetricsTimeZoneSuggestion createCertain(
|
||||
@NonNull int[] zoneIdOrdinals) {
|
||||
return new MetricsTimeZoneSuggestion(zoneIdOrdinals);
|
||||
@Nullable String[] zoneIds, @NonNull int[] zoneIdOrdinals) {
|
||||
return new MetricsTimeZoneSuggestion(zoneIds, zoneIdOrdinals);
|
||||
}
|
||||
|
||||
public boolean isCertain() {
|
||||
return mZoneIdOrdinals != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ordinals for the time zone IDs contained in the suggestion.
|
||||
* See {@link MetricsTimeZoneDetectorState} for information about ordinals.
|
||||
*/
|
||||
@Nullable
|
||||
public int[] getZoneIdOrdinals() {
|
||||
return mZoneIdOrdinals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time zone IDs contained in the suggestion. This will only be populated if
|
||||
* {@link #isEnhancedMetricsCollectionEnabled()} is {@code true}. See {@link
|
||||
* MetricsTimeZoneDetectorState} for details.
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getZoneIds() {
|
||||
return mZoneIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -290,18 +342,22 @@ public final class MetricsTimeZoneDetectorState {
|
||||
return false;
|
||||
}
|
||||
MetricsTimeZoneSuggestion that = (MetricsTimeZoneSuggestion) o;
|
||||
return Arrays.equals(mZoneIdOrdinals, that.mZoneIdOrdinals);
|
||||
return Arrays.equals(mZoneIdOrdinals, that.mZoneIdOrdinals)
|
||||
&& Arrays.equals(mZoneIds, that.mZoneIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(mZoneIdOrdinals);
|
||||
int result = Arrays.hashCode(mZoneIds);
|
||||
result = 31 * result + Arrays.hashCode(mZoneIdOrdinals);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MetricsTimeZoneSuggestion{"
|
||||
+ "mZoneIdOrdinals=" + Arrays.toString(mZoneIdOrdinals)
|
||||
+ ", mZoneIds=" + Arrays.toString(mZoneIds)
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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_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_TELEPHONY_FALLBACK_SUPPORTED,
|
||||
@@ -296,6 +297,7 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
|
||||
isTelephonyTimeZoneDetectionFeatureSupported())
|
||||
.setGeoDetectionFeatureSupported(isGeoTimeZoneDetectionFeatureSupported())
|
||||
.setTelephonyFallbackSupported(isTelephonyFallbackSupported())
|
||||
.setEnhancedMetricsCollectionEnabled(isEnhancedMetricsCollectionEnabled())
|
||||
.setAutoDetectionEnabledSetting(getAutoDetectionEnabledSetting())
|
||||
.setUserConfigAllowed(isUserConfigAllowed(userId))
|
||||
.setLocationEnabledSetting(getLocationEnabledSetting(userId))
|
||||
@@ -400,6 +402,17 @@ public final class ServiceConfigAccessorImpl implements ServiceConfigAccessor {
|
||||
defaultEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if extra metrics / telemetry information can be collected. Used for
|
||||
* internal testers.
|
||||
*/
|
||||
private boolean isEnhancedMetricsCollectionEnabled() {
|
||||
final boolean defaultEnabled = false;
|
||||
return mServerFlags.getBoolean(
|
||||
ServerFlags.KEY_ENHANCED_METRICS_COLLECTION_ENABLED,
|
||||
defaultEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public synchronized String getPrimaryLocationTimeZoneProviderPackageName() {
|
||||
|
||||
@@ -364,6 +364,13 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
MetricsTimeZoneDetectorState generateMetricsState() {
|
||||
enforceManageTimeZoneDetectorPermission();
|
||||
|
||||
return mTimeZoneDetectorStrategy.generateMetricsState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
|
||||
@Nullable String[] args) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.server.timezonedetector;
|
||||
|
||||
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_DUMP_METRICS;
|
||||
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_ENABLE_TELEPHONY_FALLBACK;
|
||||
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_IS_AUTO_DETECTION_ENABLED;
|
||||
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_IS_GEO_DETECTION_ENABLED;
|
||||
@@ -28,6 +29,7 @@ import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_SUGGES
|
||||
import static android.app.timezonedetector.TimeZoneDetector.SHELL_COMMAND_SUGGEST_TELEPHONY_TIME_ZONE;
|
||||
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_SETTING_ENABLED_DEFAULT;
|
||||
import static com.android.server.timedetector.ServerFlags.KEY_LOCATION_TIME_ZONE_DETECTION_SETTING_ENABLED_OVERRIDE;
|
||||
@@ -80,6 +82,8 @@ class TimeZoneDetectorShellCommand extends ShellCommand {
|
||||
return runSuggestTelephonyTimeZone();
|
||||
case SHELL_COMMAND_ENABLE_TELEPHONY_FALLBACK:
|
||||
return runEnableTelephonyFallback();
|
||||
case SHELL_COMMAND_DUMP_METRICS:
|
||||
return runDumpMetrics();
|
||||
default: {
|
||||
return handleDefaultCommands(cmd);
|
||||
}
|
||||
@@ -168,14 +172,22 @@ class TimeZoneDetectorShellCommand extends ShellCommand {
|
||||
pw.println("Suggestion " + suggestion + " injected.");
|
||||
return 0;
|
||||
} catch (RuntimeException e) {
|
||||
pw.println(e.toString());
|
||||
pw.println(e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private int runEnableTelephonyFallback() {
|
||||
mInterface.enableTelephonyFallback();
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runDumpMetrics() {
|
||||
final PrintWriter pw = getOutPrintWriter();
|
||||
MetricsTimeZoneDetectorState metricsState = mInterface.generateMetricsState();
|
||||
pw.println("MetricsTimeZoneDetectorState:");
|
||||
pw.println(metricsState.toString());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -208,10 +220,10 @@ class TimeZoneDetectorShellCommand extends ShellCommand {
|
||||
pw.println();
|
||||
pw.printf(" %s <geolocation suggestion opts>\n",
|
||||
SHELL_COMMAND_SUGGEST_GEO_LOCATION_TIME_ZONE);
|
||||
pw.printf(" %s <manual suggestion opts>\n",
|
||||
SHELL_COMMAND_SUGGEST_MANUAL_TIME_ZONE);
|
||||
pw.printf(" %s <telephony suggestion opts>\n",
|
||||
SHELL_COMMAND_SUGGEST_TELEPHONY_TIME_ZONE);
|
||||
pw.printf(" %s <manual suggestion opts>\n", SHELL_COMMAND_SUGGEST_MANUAL_TIME_ZONE);
|
||||
pw.printf(" %s <telephony suggestion opts>\n", SHELL_COMMAND_SUGGEST_TELEPHONY_TIME_ZONE);
|
||||
pw.printf(" %s\n", SHELL_COMMAND_DUMP_METRICS);
|
||||
pw.printf(" Dumps the service metrics to stdout for inspection.\n");
|
||||
pw.println();
|
||||
GeolocationTimeZoneSuggestion.printCommandLineOpts(pw);
|
||||
pw.println();
|
||||
@@ -235,6 +247,8 @@ class TimeZoneDetectorShellCommand extends ShellCommand {
|
||||
pw.printf(" %s\n", KEY_TIME_ZONE_DETECTOR_TELEPHONY_FALLBACK_SUPPORTED);
|
||||
pw.printf(" Used to enable / disable support for telephony detection fallback. Also see"
|
||||
+ " the %s command.\n", SHELL_COMMAND_ENABLE_TELEPHONY_FALLBACK);
|
||||
pw.printf(" %s\n", KEY_ENHANCED_METRICS_COLLECTION_ENABLED);
|
||||
pw.printf(" Used to increase the detail of metrics collected / reported.\n");
|
||||
pw.println();
|
||||
pw.printf("[*] To be enabled, the user must still have location = on / auto time zone"
|
||||
+ " detection = on.\n");
|
||||
|
||||
@@ -49,6 +49,7 @@ public class ConfigurationInternalTest {
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(true)
|
||||
@@ -112,6 +113,7 @@ public class ConfigurationInternalTest {
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(true)
|
||||
@@ -177,6 +179,7 @@ public class ConfigurationInternalTest {
|
||||
.setTelephonyDetectionFeatureSupported(false)
|
||||
.setGeoDetectionFeatureSupported(false)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(true)
|
||||
@@ -240,6 +243,7 @@ public class ConfigurationInternalTest {
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(false)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(true)
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.timezonedetector;
|
||||
|
||||
import static com.android.server.timezonedetector.MetricsTimeZoneDetectorState.DETECTION_MODE_GEO;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import android.annotation.ElapsedRealtimeLong;
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.timezonedetector.ManualTimeZoneSuggestion;
|
||||
import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
|
||||
|
||||
import com.android.server.timezonedetector.MetricsTimeZoneDetectorState.MetricsTimeZoneSuggestion;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
|
||||
/** Tests for {@link MetricsTimeZoneDetectorState}. */
|
||||
public class MetricsTimeZoneDetectorStateTest {
|
||||
|
||||
private static final @UserIdInt int ARBITRARY_USER_ID = 1;
|
||||
private static final @ElapsedRealtimeLong long ARBITRARY_ELAPSED_REALTIME_MILLIS = 1234L;
|
||||
private static final String DEVICE_TIME_ZONE_ID = "DeviceTimeZoneId";
|
||||
|
||||
private static final ManualTimeZoneSuggestion MANUAL_TIME_ZONE_SUGGESTION =
|
||||
new ManualTimeZoneSuggestion("ManualTimeZoneId");
|
||||
|
||||
private static final TelephonyTimeZoneSuggestion TELEPHONY_TIME_ZONE_SUGGESTION =
|
||||
new TelephonyTimeZoneSuggestion.Builder(0)
|
||||
.setZoneId("TelephonyZoneId")
|
||||
.setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY)
|
||||
.setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE)
|
||||
.build();
|
||||
|
||||
private static final GeolocationTimeZoneSuggestion GEOLOCATION_TIME_ZONE_SUGGESTION =
|
||||
GeolocationTimeZoneSuggestion.createCertainSuggestion(
|
||||
ARBITRARY_ELAPSED_REALTIME_MILLIS,
|
||||
Arrays.asList("GeoTimeZoneId1", "GeoTimeZoneId2"));
|
||||
|
||||
private final OrdinalGenerator<String> mOrdinalGenerator =
|
||||
new OrdinalGenerator<>(Function.identity());
|
||||
|
||||
@Test
|
||||
public void enhancedMetricsCollectionEnabled() {
|
||||
final boolean enhancedMetricsCollectionEnabled = true;
|
||||
ConfigurationInternal configurationInternal =
|
||||
createConfigurationInternal(enhancedMetricsCollectionEnabled);
|
||||
|
||||
// Create the object.
|
||||
MetricsTimeZoneDetectorState metricsTimeZoneDetectorState =
|
||||
MetricsTimeZoneDetectorState.create(mOrdinalGenerator, configurationInternal,
|
||||
DEVICE_TIME_ZONE_ID, MANUAL_TIME_ZONE_SUGGESTION,
|
||||
TELEPHONY_TIME_ZONE_SUGGESTION, GEOLOCATION_TIME_ZONE_SUGGESTION);
|
||||
|
||||
// Assert the content.
|
||||
assertCommonConfiguration(configurationInternal, metricsTimeZoneDetectorState);
|
||||
|
||||
assertEquals(DEVICE_TIME_ZONE_ID, metricsTimeZoneDetectorState.getDeviceTimeZoneId());
|
||||
MetricsTimeZoneSuggestion expectedManualSuggestion =
|
||||
MetricsTimeZoneSuggestion.createCertain(
|
||||
new String[] { MANUAL_TIME_ZONE_SUGGESTION.getZoneId() },
|
||||
new int[] { 1 });
|
||||
assertEquals(expectedManualSuggestion,
|
||||
metricsTimeZoneDetectorState.getLatestManualSuggestion());
|
||||
|
||||
MetricsTimeZoneSuggestion expectedTelephonySuggestion =
|
||||
MetricsTimeZoneSuggestion.createCertain(
|
||||
new String[] { TELEPHONY_TIME_ZONE_SUGGESTION.getZoneId() },
|
||||
new int[] { 2 });
|
||||
assertEquals(expectedTelephonySuggestion,
|
||||
metricsTimeZoneDetectorState.getLatestTelephonySuggestion());
|
||||
|
||||
MetricsTimeZoneSuggestion expectedGeoSuggestion =
|
||||
MetricsTimeZoneSuggestion.createCertain(
|
||||
GEOLOCATION_TIME_ZONE_SUGGESTION.getZoneIds().toArray(new String[0]),
|
||||
new int[] { 3, 4 });
|
||||
assertEquals(expectedGeoSuggestion,
|
||||
metricsTimeZoneDetectorState.getLatestGeolocationSuggestion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enhancedMetricsCollectionDisabled() {
|
||||
final boolean enhancedMetricsCollectionEnabled = false;
|
||||
ConfigurationInternal configurationInternal =
|
||||
createConfigurationInternal(enhancedMetricsCollectionEnabled);
|
||||
|
||||
// Create the object.
|
||||
MetricsTimeZoneDetectorState metricsTimeZoneDetectorState =
|
||||
MetricsTimeZoneDetectorState.create(mOrdinalGenerator, configurationInternal,
|
||||
DEVICE_TIME_ZONE_ID, MANUAL_TIME_ZONE_SUGGESTION,
|
||||
TELEPHONY_TIME_ZONE_SUGGESTION, GEOLOCATION_TIME_ZONE_SUGGESTION);
|
||||
|
||||
// Assert the content.
|
||||
assertCommonConfiguration(configurationInternal, metricsTimeZoneDetectorState);
|
||||
|
||||
// When enhancedMetricsCollectionEnabled == false, no time zone IDs should be included.
|
||||
assertNull(metricsTimeZoneDetectorState.getDeviceTimeZoneId());
|
||||
final String[] omittedZoneIds = null;
|
||||
|
||||
MetricsTimeZoneSuggestion expectedManualSuggestion =
|
||||
MetricsTimeZoneSuggestion.createCertain(
|
||||
omittedZoneIds,
|
||||
new int[] { 1 });
|
||||
assertEquals(expectedManualSuggestion,
|
||||
metricsTimeZoneDetectorState.getLatestManualSuggestion());
|
||||
|
||||
MetricsTimeZoneSuggestion expectedTelephonySuggestion =
|
||||
MetricsTimeZoneSuggestion.createCertain(
|
||||
omittedZoneIds,
|
||||
new int[] { 2 });
|
||||
assertEquals(expectedTelephonySuggestion,
|
||||
metricsTimeZoneDetectorState.getLatestTelephonySuggestion());
|
||||
|
||||
MetricsTimeZoneSuggestion expectedGeoSuggestion =
|
||||
MetricsTimeZoneSuggestion.createCertain(
|
||||
omittedZoneIds,
|
||||
new int[] { 3, 4 });
|
||||
assertEquals(expectedGeoSuggestion,
|
||||
metricsTimeZoneDetectorState.getLatestGeolocationSuggestion());
|
||||
}
|
||||
|
||||
private static void assertCommonConfiguration(ConfigurationInternal configurationInternal,
|
||||
MetricsTimeZoneDetectorState metricsTimeZoneDetectorState) {
|
||||
assertEquals(configurationInternal.isTelephonyDetectionSupported(),
|
||||
metricsTimeZoneDetectorState.isTelephonyDetectionSupported());
|
||||
assertEquals(configurationInternal.isGeoDetectionSupported(),
|
||||
metricsTimeZoneDetectorState.isGeoDetectionSupported());
|
||||
assertEquals(configurationInternal.getAutoDetectionEnabledSetting(),
|
||||
metricsTimeZoneDetectorState.getAutoDetectionEnabledSetting());
|
||||
assertEquals(configurationInternal.getLocationEnabledSetting(),
|
||||
metricsTimeZoneDetectorState.getUserLocationEnabledSetting());
|
||||
assertEquals(configurationInternal.getGeoDetectionEnabledSetting(),
|
||||
metricsTimeZoneDetectorState.getGeoDetectionEnabledSetting());
|
||||
assertEquals(configurationInternal.isEnhancedMetricsCollectionEnabled(),
|
||||
metricsTimeZoneDetectorState.isEnhancedMetricsCollectionEnabled());
|
||||
assertEquals(0, metricsTimeZoneDetectorState.getDeviceTimeZoneIdOrdinal());
|
||||
assertEquals(DETECTION_MODE_GEO, metricsTimeZoneDetectorState.getDetectionMode());
|
||||
}
|
||||
|
||||
private static ConfigurationInternal createConfigurationInternal(
|
||||
boolean enhancedMetricsCollectionEnabled) {
|
||||
return new ConfigurationInternal.Builder(ARBITRARY_USER_ID)
|
||||
.setUserConfigAllowed(true)
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setEnhancedMetricsCollectionEnabled(enhancedMetricsCollectionEnabled)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(true)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -379,6 +379,7 @@ public class TimeZoneDetectorServiceTest {
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setUserConfigAllowed(true)
|
||||
.setAutoDetectionEnabledSetting(autoDetectionEnabled)
|
||||
.setLocationEnabledSetting(geoDetectionEnabled)
|
||||
|
||||
@@ -87,10 +87,11 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
private static final ConfigurationInternal CONFIG_USER_RESTRICTED_AUTO_DISABLED =
|
||||
new ConfigurationInternal.Builder(USER_ID)
|
||||
.setUserConfigAllowed(false)
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setUserConfigAllowed(false)
|
||||
.setAutoDetectionEnabledSetting(false)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(false)
|
||||
@@ -98,10 +99,11 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
private static final ConfigurationInternal CONFIG_USER_RESTRICTED_AUTO_ENABLED =
|
||||
new ConfigurationInternal.Builder(USER_ID)
|
||||
.setUserConfigAllowed(false)
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setUserConfigAllowed(false)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(true)
|
||||
@@ -109,10 +111,11 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
private static final ConfigurationInternal CONFIG_AUTO_DETECT_NOT_SUPPORTED =
|
||||
new ConfigurationInternal.Builder(USER_ID)
|
||||
.setUserConfigAllowed(true)
|
||||
.setTelephonyDetectionFeatureSupported(false)
|
||||
.setGeoDetectionFeatureSupported(false)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setUserConfigAllowed(true)
|
||||
.setAutoDetectionEnabledSetting(false)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(false)
|
||||
@@ -120,10 +123,11 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
|
||||
private static final ConfigurationInternal CONFIG_AUTO_DISABLED_GEO_DISABLED =
|
||||
new ConfigurationInternal.Builder(USER_ID)
|
||||
.setUserConfigAllowed(true)
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setUserConfigAllowed(true)
|
||||
.setAutoDetectionEnabledSetting(false)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(false)
|
||||
@@ -134,6 +138,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setUserConfigAllowed(true)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
@@ -145,6 +150,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setUserConfigAllowed(true)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
@@ -955,8 +961,20 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateMetricsState() {
|
||||
ConfigurationInternal expectedInternalConfig = CONFIG_AUTO_DISABLED_GEO_DISABLED;
|
||||
public void testGenerateMetricsState_enhancedMetricsCollection() {
|
||||
testGenerateMetricsState(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateMetricsState_notEnhancedMetricsCollection() {
|
||||
testGenerateMetricsState(false);
|
||||
}
|
||||
|
||||
private void testGenerateMetricsState(boolean enhancedMetricsCollection) {
|
||||
ConfigurationInternal expectedInternalConfig =
|
||||
new ConfigurationInternal.Builder(CONFIG_AUTO_DISABLED_GEO_DISABLED)
|
||||
.setEnhancedMetricsCollectionEnabled(enhancedMetricsCollection)
|
||||
.build();
|
||||
String expectedDeviceTimeZoneId = "InitialZoneId";
|
||||
|
||||
Script script = new Script()
|
||||
@@ -1028,7 +1046,7 @@ public class TimeZoneDetectorStrategyImplTest {
|
||||
tzIdOrdinalGenerator, expectedInternalConfig, expectedDeviceTimeZoneId,
|
||||
expectedManualSuggestion, expectedTelephonySuggestion,
|
||||
expectedGeolocationTimeZoneSuggestion);
|
||||
// Rely on MetricsTimeZoneDetectorState.equals() for time zone ID ordinal comparisons.
|
||||
// Rely on MetricsTimeZoneDetectorState.equals() for time zone ID / ID ordinal comparisons.
|
||||
assertEquals(expectedState, actualState);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ final class TestSupport {
|
||||
.setTelephonyDetectionFeatureSupported(true)
|
||||
.setGeoDetectionFeatureSupported(true)
|
||||
.setTelephonyFallbackSupported(false)
|
||||
.setEnhancedMetricsCollectionEnabled(false)
|
||||
.setAutoDetectionEnabledSetting(true)
|
||||
.setLocationEnabledSetting(true)
|
||||
.setGeoDetectionEnabledSetting(geoDetectionEnabledSetting)
|
||||
|
||||
Reference in New Issue
Block a user