diff --git a/core/java/android/app/time/TimeZoneCapabilities.java b/core/java/android/app/time/TimeZoneCapabilities.java index b647fc33055da..4dee159887957 100644 --- a/core/java/android/app/time/TimeZoneCapabilities.java +++ b/core/java/android/app/time/TimeZoneCapabilities.java @@ -57,6 +57,16 @@ public final class TimeZoneCapabilities implements Parcelable { */ @NonNull private final UserHandle mUserHandle; private final @CapabilityState int mConfigureAutoDetectionEnabledCapability; + + /** + * The values of the user's "Use location" value, AKA the Master Location Switch. + * + *
This is only exposed for SettingsUI and so is not part of the SDK API. + * + *
This is not treated as a CapabilityState as it's a boolean value that all user's have. + */ + private final boolean mUseLocationEnabled; + private final @CapabilityState int mConfigureGeoDetectionEnabledCapability; private final @CapabilityState int mSetManualTimeZoneCapability; @@ -64,6 +74,7 @@ public final class TimeZoneCapabilities implements Parcelable { this.mUserHandle = Objects.requireNonNull(builder.mUserHandle); this.mConfigureAutoDetectionEnabledCapability = builder.mConfigureAutoDetectionEnabledCapability; + this.mUseLocationEnabled = builder.mUseLocationEnabled; this.mConfigureGeoDetectionEnabledCapability = builder.mConfigureGeoDetectionEnabledCapability; this.mSetManualTimeZoneCapability = builder.mSetManualTimeZoneCapability; @@ -74,6 +85,7 @@ public final class TimeZoneCapabilities implements Parcelable { UserHandle userHandle = UserHandle.readFromParcel(in); return new TimeZoneCapabilities.Builder(userHandle) .setConfigureAutoDetectionEnabledCapability(in.readInt()) + .setUseLocationEnabled(in.readBoolean()) .setConfigureGeoDetectionEnabledCapability(in.readInt()) .setSetManualTimeZoneCapability(in.readInt()) .build(); @@ -83,6 +95,7 @@ public final class TimeZoneCapabilities implements Parcelable { public void writeToParcel(@NonNull Parcel dest, int flags) { UserHandle.writeToParcel(mUserHandle, dest); dest.writeInt(mConfigureAutoDetectionEnabledCapability); + dest.writeBoolean(mUseLocationEnabled); dest.writeInt(mConfigureGeoDetectionEnabledCapability); dest.writeInt(mSetManualTimeZoneCapability); } @@ -97,6 +110,20 @@ public final class TimeZoneCapabilities implements Parcelable { return mConfigureAutoDetectionEnabledCapability; } + /** + * Returns {@code true} if the device's location can be used by the Android system, and + * therefore the platform components running on behalf of the user. At the time of writing, the + * user can change this via the "Use location" setting on the Location settings screen. + * + * Not part of the SDK API because it is intended for use by SettingsUI, which can display + * text about needing it to be on for location-based time zone detection. + * @hide + * + */ + public boolean isUseLocationEnabled() { + return mUseLocationEnabled; + } + /** * Returns the capability state associated with the user's ability to modify the geolocation * detection setting. The setting can be updated via {@link @@ -167,6 +194,7 @@ public final class TimeZoneCapabilities implements Parcelable { return mUserHandle.equals(that.mUserHandle) && mConfigureAutoDetectionEnabledCapability == that.mConfigureAutoDetectionEnabledCapability + && mUseLocationEnabled == that.mUseLocationEnabled && mConfigureGeoDetectionEnabledCapability == that.mConfigureGeoDetectionEnabledCapability && mSetManualTimeZoneCapability == that.mSetManualTimeZoneCapability; @@ -184,6 +212,7 @@ public final class TimeZoneCapabilities implements Parcelable { + "mUserHandle=" + mUserHandle + ", mConfigureAutoDetectionEnabledCapability=" + mConfigureAutoDetectionEnabledCapability + + ", mUseLocationEnabled=" + mUseLocationEnabled + ", mConfigureGeoDetectionEnabledCapability=" + mConfigureGeoDetectionEnabledCapability + ", mSetManualTimeZoneCapability=" + mSetManualTimeZoneCapability @@ -199,6 +228,7 @@ public final class TimeZoneCapabilities implements Parcelable { @NonNull private UserHandle mUserHandle; private @CapabilityState int mConfigureAutoDetectionEnabledCapability; + private Boolean mUseLocationEnabled; private @CapabilityState int mConfigureGeoDetectionEnabledCapability; private @CapabilityState int mSetManualTimeZoneCapability; @@ -211,6 +241,7 @@ public final class TimeZoneCapabilities implements Parcelable { mUserHandle = capabilitiesToCopy.mUserHandle; mConfigureAutoDetectionEnabledCapability = capabilitiesToCopy.mConfigureAutoDetectionEnabledCapability; + mUseLocationEnabled = capabilitiesToCopy.mUseLocationEnabled; mConfigureGeoDetectionEnabledCapability = capabilitiesToCopy.mConfigureGeoDetectionEnabledCapability; mSetManualTimeZoneCapability = @@ -223,6 +254,12 @@ public final class TimeZoneCapabilities implements Parcelable { return this; } + /** Sets the values for "use location". See {@link #isUseLocationEnabled()}. */ + public Builder setUseLocationEnabled(boolean useLocation) { + mUseLocationEnabled = useLocation; + return this; + } + /** * Sets the value for the "configure geolocation time zone detection enabled" capability. */ @@ -242,6 +279,7 @@ public final class TimeZoneCapabilities implements Parcelable { public TimeZoneCapabilities build() { verifyCapabilitySet(mConfigureAutoDetectionEnabledCapability, "configureAutoDetectionEnabledCapability"); + Objects.requireNonNull(mUseLocationEnabled, "useLocationEnabled"); verifyCapabilitySet(mConfigureGeoDetectionEnabledCapability, "configureGeoDetectionEnabledCapability"); verifyCapabilitySet(mSetManualTimeZoneCapability, diff --git a/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java b/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java index 8bed31f4821a5..6636cbdac1012 100644 --- a/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java +++ b/core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java @@ -44,10 +44,12 @@ public class TimeZoneCapabilitiesTest { public void testEquals() { TimeZoneCapabilities.Builder builder1 = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED) .setSetManualTimeZoneCapability(CAPABILITY_POSSESSED); TimeZoneCapabilities.Builder builder2 = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED) .setSetManualTimeZoneCapability(CAPABILITY_POSSESSED); { @@ -70,6 +72,20 @@ public class TimeZoneCapabilitiesTest { assertEquals(one, two); } + builder2.setUseLocationEnabled(false); + { + TimeZoneCapabilities one = builder1.build(); + TimeZoneCapabilities two = builder2.build(); + assertNotEquals(one, two); + } + + builder1.setUseLocationEnabled(false); + { + TimeZoneCapabilities one = builder1.build(); + TimeZoneCapabilities two = builder2.build(); + assertEquals(one, two); + } + builder2.setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED); { TimeZoneCapabilities one = builder1.build(); @@ -103,6 +119,7 @@ public class TimeZoneCapabilitiesTest { public void testParcelable() { TimeZoneCapabilities.Builder builder = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED) .setSetManualTimeZoneCapability(CAPABILITY_POSSESSED); assertRoundTripParcelable(builder.build()); @@ -110,6 +127,9 @@ public class TimeZoneCapabilitiesTest { builder.setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED); assertRoundTripParcelable(builder.build()); + builder.setUseLocationEnabled(false); + assertRoundTripParcelable(builder.build()); + builder.setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED); assertRoundTripParcelable(builder.build()); @@ -126,6 +146,7 @@ public class TimeZoneCapabilitiesTest { .build(); TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED) .setSetManualTimeZoneCapability(CAPABILITY_POSSESSED) .build(); @@ -149,6 +170,7 @@ public class TimeZoneCapabilitiesTest { .build(); TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) .setSetManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED) .build(); @@ -164,6 +186,7 @@ public class TimeZoneCapabilitiesTest { public void copyBuilder_copiesAllFields() { TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) .setSetManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED) .build(); @@ -176,6 +199,24 @@ public class TimeZoneCapabilitiesTest { TimeZoneCapabilities expectedCapabilities = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED) + .setUseLocationEnabled(true) + .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) + .setSetManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED) + .build(); + + assertThat(updatedCapabilities).isEqualTo(expectedCapabilities); + } + + { + TimeZoneCapabilities updatedCapabilities = + new TimeZoneCapabilities.Builder(capabilities) + .setUseLocationEnabled(false) + .build(); + + TimeZoneCapabilities expectedCapabilities = + new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) + .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) + .setUseLocationEnabled(false) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) .setSetManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED) .build(); @@ -192,6 +233,7 @@ public class TimeZoneCapabilitiesTest { TimeZoneCapabilities expectedCapabilities = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED) .setSetManualTimeZoneCapability(CAPABILITY_NOT_ALLOWED) .build(); @@ -208,6 +250,7 @@ public class TimeZoneCapabilitiesTest { TimeZoneCapabilities expectedCapabilities = new TimeZoneCapabilities.Builder(TEST_USER_HANDLE) .setConfigureAutoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) + .setUseLocationEnabled(true) .setConfigureGeoDetectionEnabledCapability(CAPABILITY_NOT_ALLOWED) .setSetManualTimeZoneCapability(CAPABILITY_POSSESSED) .build(); diff --git a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java index 111b4f6ee2a1d..5fd70a891b663 100644 --- a/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java +++ b/services/core/java/com/android/server/timezonedetector/ConfigurationInternal.java @@ -243,6 +243,8 @@ public final class ConfigurationInternal { } builder.setConfigureAutoDetectionEnabledCapability(configureAutoDetectionEnabledCapability); + builder.setUseLocationEnabled(mLocationEnabledSetting); + boolean deviceHasLocationTimeZoneDetection = isGeoDetectionSupported(); boolean deviceHasTelephonyDetection = isTelephonyDetectionSupported();