diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8aca71a9dc8..9c87e87aeb8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4092,6 +4092,18 @@
Use location to set time zone
+
+ Device location needed
+
+ To set the time zone using your location, turn on location, then update time zone settings
+
+ Location settings
+
+ Cancel
diff --git a/src/com/android/settings/datetime/DateTimeSettings.java b/src/com/android/settings/datetime/DateTimeSettings.java
index 469a4c7e1b8..d74847f1411 100644
--- a/src/com/android/settings/datetime/DateTimeSettings.java
+++ b/src/com/android/settings/datetime/DateTimeSettings.java
@@ -59,6 +59,7 @@ public class DateTimeSettings extends DashboardFragment implements
public void onAttach(Context context) {
super.onAttach(context);
getSettingsLifecycle().addObserver(new TimeChangeListenerMixin(context, this));
+ use(LocationTimeZoneDetectionPreferenceController.class).setFragment(this);
}
@Override
@@ -77,6 +78,7 @@ public class DateTimeSettings extends DashboardFragment implements
final AutoTimeFormatPreferenceController autoTimeFormatPreferenceController =
new AutoTimeFormatPreferenceController(
activity, this /* UpdateTimeAndDateCallback */);
+
controllers.add(autoTimeZonePreferenceController);
controllers.add(autoTimePreferenceController);
controllers.add(autoTimeFormatPreferenceController);
diff --git a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
index 0b0fa27f62c..cb39635cc43 100644
--- a/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
+++ b/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceController.java
@@ -31,6 +31,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
+import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
@@ -46,17 +47,24 @@ public class LocationTimeZoneDetectionPreferenceController
extends TogglePreferenceController
implements LifecycleObserver, OnStart, OnStop, TimeManager.TimeZoneDetectorListener {
+ private static final String TAG = "location_time_zone_detection";
+
private final TimeManager mTimeManager;
private final LocationManager mLocationManager;
private TimeZoneCapabilitiesAndConfig mTimeZoneCapabilitiesAndConfig;
+ private InstrumentedPreferenceFragment mFragment;
private Preference mPreference;
- public LocationTimeZoneDetectionPreferenceController(Context context, String key) {
- super(context, key);
+ public LocationTimeZoneDetectionPreferenceController(Context context) {
+ super(context, TAG);
mTimeManager = context.getSystemService(TimeManager.class);
mLocationManager = context.getSystemService(LocationManager.class);
}
+ void setFragment(InstrumentedPreferenceFragment fragment) {
+ mFragment = fragment;
+ }
+
@Override
public boolean isChecked() {
TimeZoneCapabilitiesAndConfig capabilitiesAndConfig =
@@ -67,10 +75,17 @@ public class LocationTimeZoneDetectionPreferenceController
@Override
public boolean setChecked(boolean isChecked) {
- TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
- .setGeoDetectionEnabled(isChecked)
- .build();
- return mTimeManager.updateTimeZoneConfiguration(configuration);
+ if (isChecked && !mLocationManager.isLocationEnabled()) {
+ new LocationToggleDisabledDialogFragment(mContext)
+ .show(mFragment.getFragmentManager(), TAG);
+ // Toggle status is not updated.
+ return false;
+ } else {
+ TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder()
+ .setGeoDetectionEnabled(isChecked)
+ .build();
+ return mTimeManager.updateTimeZoneConfiguration(configuration);
+ }
}
@Override
diff --git a/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java b/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java
new file mode 100644
index 00000000000..61d46c67b0a
--- /dev/null
+++ b/src/com/android/settings/datetime/LocationToggleDisabledDialogFragment.java
@@ -0,0 +1,63 @@
+/*
+ * 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.settings.datetime;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+/**
+ * Dialog shown when user tries to enable GeoTZ with Location toggle disabled.
+ */
+public class LocationToggleDisabledDialogFragment extends InstrumentedDialogFragment {
+
+ private final Context mContext;
+
+ public LocationToggleDisabledDialogFragment(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.location_time_zone_detection_location_is_off_dialog_title)
+ .setIcon(R.drawable.ic_warning_24dp)
+ .setMessage(R.string.location_time_zone_detection_location_is_off_dialog_message)
+ .setPositiveButton(
+ R.string.location_time_zone_detection_location_is_off_dialog_ok_button,
+ (dialog, which) -> {
+ Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+ mContext.startActivity(intent);
+ })
+ .setNegativeButton(
+ R.string.location_time_zone_detection_location_is_off_dialog_cancel_button,
+ (dialog, which) -> {})
+ .create();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.DIALOG_DATE_TIME_ENABLE_GEOTZ_WITH_DISABLED_LOCATION;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
index 68b2990a03b..1262b5045a7 100644
--- a/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/LocationTimeZoneDetectionPreferenceControllerTest.java
@@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.time.Capabilities;
@@ -36,10 +37,13 @@ import android.location.LocationManager;
import android.os.UserHandle;
import com.android.settings.R;
+import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -53,6 +57,10 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
private LocationManager mLocationManager;
private Context mContext;
private LocationTimeZoneDetectionPreferenceController mController;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private InstrumentedPreferenceFragment mFragment;
+ @Mock
+ private Lifecycle mLifecycle;
@Before
public void setUp() {
@@ -60,11 +68,14 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(TimeManager.class)).thenReturn(mTimeManager);
when(mContext.getSystemService(LocationManager.class)).thenReturn(mLocationManager);
- mController = new LocationTimeZoneDetectionPreferenceController(mContext, "key");
+ mController = new LocationTimeZoneDetectionPreferenceController(mContext);
+ mController.setFragment(mFragment);
}
@Test
- public void setChecked_withTrue_shouldUpdateSetting() {
+ public void setChecked_withTrue_shouldUpdateSetting_whenLocationIsEnabled() {
+ when(mLocationManager.isLocationEnabled()).thenReturn(true);
+
// Simulate the UI being clicked.
mController.setChecked(true);
@@ -75,6 +86,17 @@ public class LocationTimeZoneDetectionPreferenceControllerTest {
verify(mTimeManager).updateTimeZoneConfiguration(expectedConfiguration);
}
+ @Test
+ public void setChecked_withTrue_shouldDoNothing_whenLocationIsDisabled() {
+ when(mLocationManager.isLocationEnabled()).thenReturn(false);
+
+ // Simulate the UI being clicked.
+ mController.setChecked(true);
+
+ // Verify the TimeManager was not called.
+ verifyZeroInteractions(mTimeManager);
+ }
+
@Test
public void setChecked_withFalse_shouldUpdateSetting() {
// Simulate the UI being clicked.