From c3b2e0bfe9c6b599b9c9e4543701aa0392c2da8f Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Tue, 17 Jan 2023 17:32:22 +0000 Subject: [PATCH] Add "Use location" state to TimeZoneCapabilities Add the user's "Use location" state to TimeZoneCapabilities. This information is available anyway and saves the SettingsUI needing to call LocationManager directly (with the small possibility it would get an inconsistent answer). Bug: 262407244 Test: atest core/tests/coretests/src/android/app/time/TimeZoneCapabilitiesTest.java Change-Id: I0369bd4907584ebd741d47b762792ffbb23c36bf --- .../app/time/TimeZoneCapabilities.java | 38 ++++++++++++++++ .../app/time/TimeZoneCapabilitiesTest.java | 43 +++++++++++++++++++ .../ConfigurationInternal.java | 2 + 3 files changed, 83 insertions(+) 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();