From 1affbfff83a9ae8a712c1ee1c997d48f7a910d77 Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 23 Oct 2020 16:36:48 +0100 Subject: [PATCH] Fix review comments location_time_zone_detection Fix review comments for location_time_zone_detection.xml and associated classes from http://ag/12792958. Bug: 152746236 Test: Manual: build / boot / toggle switch in SettingsUI / inspect output of adb shell dumpsys time_zone_detector Test: Manual: build / boot / install TestDPC / toggle switch in work profile in SettingsUI / inspect output of adb shell dumpsys time_zone_detector Test: m -j30 RunSettingsRoboTests ROBOTEST_FILTER="com.android.settings.location.TimeZoneDetectionPreferenceControllerTest" Test: m -j30 RunSettingsRoboTests ROBOTEST_FILTER="com.android.settings.location.LocationTimeZoneDetectionPreferenceControllerTest" Test: m -j30 RunSettingsRoboTests ROBOTEST_FILTER="com.android.settings.location.TimeZoneDetectionSettingsTest" Change-Id: I641f312cd63359f45664a93e009e5a975dbd6485 --- res/xml/location_time_zone_detection.xml | 5 +- .../location/LocationPersonalSettings.java | 2 - .../settings/location/LocationSettings.java | 1 - ...TimeZoneDetectionPreferenceController.java | 97 ---------- .../location/TimeZoneDetectionSettings.java | 25 +-- ...neDetectionTogglePreferenceController.java | 59 ++++++ ...ZoneDetectionPreferenceControllerTest.java | 174 ------------------ ...tectionTogglePreferenceControllerTest.java | 119 ++++++++++++ 8 files changed, 183 insertions(+), 299 deletions(-) delete mode 100644 src/com/android/settings/location/TimeZoneDetectionPreferenceController.java create mode 100644 src/com/android/settings/location/TimeZoneDetectionTogglePreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/location/TimeZoneDetectionPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/location/TimeZoneDetectionTogglePreferenceControllerTest.java diff --git a/res/xml/location_time_zone_detection.xml b/res/xml/location_time_zone_detection.xml index 91e7847c541..7f0c2488c46 100644 --- a/res/xml/location_time_zone_detection.xml +++ b/res/xml/location_time_zone_detection.xml @@ -14,12 +14,15 @@ limitations under the License. --> - diff --git a/src/com/android/settings/location/LocationPersonalSettings.java b/src/com/android/settings/location/LocationPersonalSettings.java index 3f90896fba2..92796a4bd66 100644 --- a/src/com/android/settings/location/LocationPersonalSettings.java +++ b/src/com/android/settings/location/LocationPersonalSettings.java @@ -58,8 +58,6 @@ public class LocationPersonalSettings extends DashboardFragment { RecentLocationRequestPreferenceController.class); controller.init(this); controller.setProfileType(profileType); - - use(LocationTimeZoneDetectionPreferenceController.class); } @Override diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 248620b3fef..43918111cca 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -88,7 +88,6 @@ public class LocationSettings extends DashboardFragment { use(LocationFooterPreferenceController.class).init(this); use(LocationForWorkPreferenceController.class).init(this); use(LocationServiceForWorkPreferenceController.class).init(this); - use(LocationTimeZoneDetectionPreferenceController.class); } @Override diff --git a/src/com/android/settings/location/TimeZoneDetectionPreferenceController.java b/src/com/android/settings/location/TimeZoneDetectionPreferenceController.java deleted file mode 100644 index 946376d77fa..00000000000 --- a/src/com/android/settings/location/TimeZoneDetectionPreferenceController.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2020 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.location; - -import android.app.time.TimeManager; -import android.app.time.TimeZoneCapabilitiesAndConfig; -import android.app.time.TimeZoneConfiguration; -import android.content.Context; -import android.text.TextUtils; - -import androidx.preference.Preference; -import androidx.preference.SwitchPreference; - -import com.android.settingslib.core.AbstractPreferenceController; - -/** - * The controller for the "location time zone detection" switch on the location time zone detection - * screen. - */ -public class TimeZoneDetectionPreferenceController extends AbstractPreferenceController { - - private static final String KEY_LOCATION_TIME_ZONE_DETECTION_ENABLED = - "location_time_zone_detection_enabled"; - - private final TimeManager mTimeManager; - - public TimeZoneDetectionPreferenceController(Context context) { - super(context); - mTimeManager = context.getSystemService(TimeManager.class); - } - - @Override - public boolean isAvailable() { - return true; - } - - @Override - public String getPreferenceKey() { - return KEY_LOCATION_TIME_ZONE_DETECTION_ENABLED; - } - - @Override - public void updateState(Preference preference) { - TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = - mTimeManager.getTimeZoneCapabilitiesAndConfig(); - setPreferenceUiState((SwitchPreference) preference, capabilitiesAndConfig); - } - - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - if (TextUtils.equals(preference.getKey(), KEY_LOCATION_TIME_ZONE_DETECTION_ENABLED)) { - SwitchPreference switchPreference = (SwitchPreference) preference; - final boolean switchState = switchPreference.isChecked(); - - // Update the settings to match the UI. - TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder() - .setGeoDetectionEnabled(switchState) - .build(); - - // The return value is ignored, but the current state is read back below ensuring it - // does not matter. - mTimeManager.updateTimeZoneConfiguration(configuration); - - // Configure the UI preference state from the configuration. This means that even in the - // unlikely event that the update failed, the UI should reflect current settings. - setPreferenceUiState(switchPreference, mTimeManager.getTimeZoneCapabilitiesAndConfig()); - - return true; - } - return false; - } - - /** - * Sets the switch's checked state from the supplied {@link TimeZoneCapabilitiesAndConfig}. - */ - @android.annotation.UiThread - private void setPreferenceUiState(SwitchPreference preference, - TimeZoneCapabilitiesAndConfig timeZoneCapabilitiesAndConfig) { - TimeZoneConfiguration configuration = timeZoneCapabilitiesAndConfig.getConfiguration(); - boolean checked = configuration.isGeoDetectionEnabled(); - preference.setChecked(checked); - } -} diff --git a/src/com/android/settings/location/TimeZoneDetectionSettings.java b/src/com/android/settings/location/TimeZoneDetectionSettings.java index 555d9d47092..66e2f9a4802 100644 --- a/src/com/android/settings/location/TimeZoneDetectionSettings.java +++ b/src/com/android/settings/location/TimeZoneDetectionSettings.java @@ -16,17 +16,12 @@ package com.android.settings.location; import android.app.settings.SettingsEnums; -import android.content.Context; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.search.SearchIndexable; -import java.util.ArrayList; -import java.util.List; - /** * The controller for the "location time zone detection" screen. */ @@ -49,27 +44,9 @@ public class TimeZoneDetectionSettings extends DashboardFragment { return TAG; } - @Override - protected List createPreferenceControllers(Context context) { - return buildPreferenceControllers(context); - } - - private static List buildPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - controllers.add(new TimeZoneDetectionPreferenceController(context)); - return controllers; - } - /** * For Search. */ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.location_time_zone_detection) { - - @Override - public List createPreferenceControllers(Context - context) { - return buildPreferenceControllers(context); - } - }; + new BaseSearchIndexProvider(R.xml.location_time_zone_detection); } diff --git a/src/com/android/settings/location/TimeZoneDetectionTogglePreferenceController.java b/src/com/android/settings/location/TimeZoneDetectionTogglePreferenceController.java new file mode 100644 index 00000000000..f23c9f9addf --- /dev/null +++ b/src/com/android/settings/location/TimeZoneDetectionTogglePreferenceController.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 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.location; + +import android.app.time.TimeManager; +import android.app.time.TimeZoneCapabilitiesAndConfig; +import android.app.time.TimeZoneConfiguration; +import android.content.Context; + +import com.android.settings.core.TogglePreferenceController; + +/** + * The controller for the "location time zone detection" switch on the location time zone detection + * screen. + */ +public class TimeZoneDetectionTogglePreferenceController extends TogglePreferenceController { + + private final TimeManager mTimeManager; + + public TimeZoneDetectionTogglePreferenceController(Context context, String key) { + super(context, key); + mTimeManager = context.getSystemService(TimeManager.class); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public boolean isChecked() { + TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = + mTimeManager.getTimeZoneCapabilitiesAndConfig(); + TimeZoneConfiguration configuration = capabilitiesAndConfig.getConfiguration(); + return configuration.isGeoDetectionEnabled(); + } + + @Override + public boolean setChecked(boolean isChecked) { + TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder() + .setGeoDetectionEnabled(isChecked) + .build(); + return mTimeManager.updateTimeZoneConfiguration(configuration); + } +} diff --git a/tests/robotests/src/com/android/settings/location/TimeZoneDetectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/TimeZoneDetectionPreferenceControllerTest.java deleted file mode 100644 index de6be5618cc..00000000000 --- a/tests/robotests/src/com/android/settings/location/TimeZoneDetectionPreferenceControllerTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2017 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.location; - -import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE; -import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.time.TimeManager; -import android.app.time.TimeZoneCapabilities; -import android.app.time.TimeZoneCapabilitiesAndConfig; -import android.app.time.TimeZoneConfiguration; -import android.content.ContentResolver; -import android.content.Context; -import android.os.UserHandle; - -import androidx.preference.SwitchPreference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class TimeZoneDetectionPreferenceControllerTest { - - @Mock - private SwitchPreference mPreference; - @Mock - private TimeManager mTimeManager; - - private Context mContext; - private ContentResolver mContentResolver; - private TimeZoneDetectionPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContentResolver = RuntimeEnvironment.application.getContentResolver(); - mContext = spy(RuntimeEnvironment.application); - when(mContext.getSystemService(TimeManager.class)).thenReturn(mTimeManager); - - mController = new TimeZoneDetectionPreferenceController(mContext); - when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); - } - - @Test - public void updateState_locationDetectionEnabled_shouldCheckPreference() { - TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = - createTimeZoneCapabilitiesAndConfig(/* geoDetectionEnabled= */ true); - when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig); - - mController.updateState(mPreference); - - verify(mPreference).setChecked(true); - } - - @Test - public void updateState_locationDetectionDisabled_shouldUncheckPreference() { - TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = - createTimeZoneCapabilitiesAndConfig(/* geoDetectionEnabled= */ false); - when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig); - - mController.updateState(mPreference); - - verify(mPreference).setChecked(false); - } - - @Test - public void handlePreferenceTreeClick_unchecked_shouldDisableGeoDetection() { - // getTimeZoneCapabilitiesAndConfig() is called after updateTimeZoneConfiguration() to - // obtain the new state. - boolean postUpdateResponseValue = false; - TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createTimeZoneCapabilitiesAndConfig( - /* geoDetectionEnabled= */postUpdateResponseValue); - when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig); - - // Simulate the UI being clicked. - boolean preferenceCheckedState = false; - when(mPreference.isChecked()).thenReturn(preferenceCheckedState); - mController.handlePreferenceTreeClick(mPreference); - - // Verify the TimeManager was updated with the UI value. - TimeZoneConfiguration expectedConfiguration = new TimeZoneConfiguration.Builder() - .setGeoDetectionEnabled(preferenceCheckedState) - .build(); - verify(mTimeManager).updateTimeZoneConfiguration(expectedConfiguration); - - // Confirm the UI state was reset using the getTimeZoneCapabilitiesAndConfig() response. - verify(mPreference).setChecked(postUpdateResponseValue); - } - - @Test - public void handlePreferenceTreeClick_checked_shouldEnableGeoDetection() { - // getTimeZoneCapabilitiesAndConfig() is called after updateTimeZoneConfiguration() to - // obtain the new state. - boolean postUpdateResponseValue = true; - TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createTimeZoneCapabilitiesAndConfig( - /* geoDetectionEnabled= */ postUpdateResponseValue); - when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig); - - // Simulate the UI being clicked. - boolean preferenceCheckedState = true; - when(mPreference.isChecked()).thenReturn(preferenceCheckedState); - mController.handlePreferenceTreeClick(mPreference); - - // Verify the TimeManager was updated with the UI value. - TimeZoneConfiguration expectedConfiguration = new TimeZoneConfiguration.Builder() - .setGeoDetectionEnabled(preferenceCheckedState) - .build(); - verify(mTimeManager).updateTimeZoneConfiguration(expectedConfiguration); - - // Confirm the UI state was reset using the getTimeZoneCapabilitiesAndConfig() response. - verify(mPreference).setChecked(postUpdateResponseValue); - } - - @Test - public void handlePreferenceTreeClick_checked_shouldEnableGeoDetection_updateRefused() { - // getTimeZoneCapabilitiesAndConfig() is called after updateTimeZoneConfiguration() to - // obtain the new state. - boolean postUpdateResponseValue = false; - TimeZoneCapabilitiesAndConfig capabilitiesAndConfig = createTimeZoneCapabilitiesAndConfig( - /* geoDetectionEnabled= */ postUpdateResponseValue); - when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig); - - // Simulate the UI being clicked. - boolean preferenceCheckedState = true; - when(mPreference.isChecked()).thenReturn(preferenceCheckedState); - mController.handlePreferenceTreeClick(mPreference); - - // Verify the TimeManager was updated with the UI value. - TimeZoneConfiguration expectedConfiguration = new TimeZoneConfiguration.Builder() - .setGeoDetectionEnabled(preferenceCheckedState) - .build(); - verify(mTimeManager).updateTimeZoneConfiguration(expectedConfiguration); - - // Confirm the UI state was reset using the getTimeZoneCapabilitiesAndConfig() response. - verify(mPreference).setChecked(postUpdateResponseValue); - } - - private static TimeZoneCapabilitiesAndConfig createTimeZoneCapabilitiesAndConfig( - boolean geoDetectionEnabled) { - UserHandle arbitraryUserHandle = UserHandle.of(123); - TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(arbitraryUserHandle) - .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED) - .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED) - .setSuggestManualTimeZoneCapability(CAPABILITY_NOT_APPLICABLE) - .build(); - TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder() - .setAutoDetectionEnabled(true) - .setGeoDetectionEnabled(geoDetectionEnabled) - .build(); - return new TimeZoneCapabilitiesAndConfig(capabilities, configuration); - } -} diff --git a/tests/robotests/src/com/android/settings/location/TimeZoneDetectionTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/TimeZoneDetectionTogglePreferenceControllerTest.java new file mode 100644 index 00000000000..a78499c7cc8 --- /dev/null +++ b/tests/robotests/src/com/android/settings/location/TimeZoneDetectionTogglePreferenceControllerTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2017 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.location; + +import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE; +import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.time.TimeManager; +import android.app.time.TimeZoneCapabilities; +import android.app.time.TimeZoneCapabilitiesAndConfig; +import android.app.time.TimeZoneConfiguration; +import android.content.Context; +import android.os.UserHandle; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class TimeZoneDetectionTogglePreferenceControllerTest { + + private static final String PREF_KEY = "test_key"; + + @Mock + private Context mContext; + + @Mock + private TimeManager mTimeManager; + private TimeZoneDetectionTogglePreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mContext.getSystemService(TimeManager.class)).thenReturn(mTimeManager); + + mController = new TimeZoneDetectionTogglePreferenceController(mContext, PREF_KEY); + } + + @Test + public void isAvailable_shouldReturnTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isChecked_whenEnabled_shouldReturnTrue() { + when(mTimeManager.getTimeZoneCapabilitiesAndConfig()) + .thenReturn(createTimeZoneCapabilitiesAndConfig(true)); + + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void isChecked_whenDisabled_shouldReturnFalse() { + when(mTimeManager.getTimeZoneCapabilitiesAndConfig()) + .thenReturn(createTimeZoneCapabilitiesAndConfig(false)); + + assertThat(mController.isChecked()).isFalse(); + } + + @Test + public void setChecked_withTrue_shouldUpdateSetting() { + // Simulate the UI being clicked. + mController.setChecked(true); + + // Verify the TimeManager was updated with the UI value. + TimeZoneConfiguration expectedConfiguration = new TimeZoneConfiguration.Builder() + .setGeoDetectionEnabled(true) + .build(); + verify(mTimeManager).updateTimeZoneConfiguration(expectedConfiguration); + } + + @Test + public void setChecked_withFalse_shouldUpdateSetting() { + // Simulate the UI being clicked. + mController.setChecked(false); + + // Verify the TimeManager was updated with the UI value. + TimeZoneConfiguration expectedConfiguration = new TimeZoneConfiguration.Builder() + .setGeoDetectionEnabled(false) + .build(); + verify(mTimeManager).updateTimeZoneConfiguration(expectedConfiguration); + } + + private static TimeZoneCapabilitiesAndConfig createTimeZoneCapabilitiesAndConfig( + boolean geoDetectionEnabled) { + UserHandle arbitraryUserHandle = UserHandle.of(123); + TimeZoneCapabilities capabilities = new TimeZoneCapabilities.Builder(arbitraryUserHandle) + .setConfigureAutoDetectionEnabledCapability(CAPABILITY_POSSESSED) + .setConfigureGeoDetectionEnabledCapability(CAPABILITY_POSSESSED) + .setSuggestManualTimeZoneCapability(CAPABILITY_NOT_APPLICABLE) + .build(); + TimeZoneConfiguration configuration = new TimeZoneConfiguration.Builder() + .setAutoDetectionEnabled(true) + .setGeoDetectionEnabled(geoDetectionEnabled) + .build(); + return new TimeZoneCapabilitiesAndConfig(capabilities, configuration); + } +}