From 2e52b42e3b1ea0762ca3cac9d809a5f720d87175 Mon Sep 17 00:00:00 2001 From: Alex Salo Date: Fri, 5 May 2017 15:36:27 -0700 Subject: [PATCH] Location setting now updates summary timely. Subscribed the LocationPreferenceController to listen to the location providers changed action. This allows timely summary update. Previous approach, directly calling the updateSummary method onResume failed in the scenario when user changed the location settings via the QuickSettings. Test: Added robolectric tests, and manually verified the intended behavior on a device. Bug: 37956060 Change-Id: I2f81713d59da3384f3c98b327d377d529d440a88 --- .../android/settings/SecuritySettings.java | 7 +- .../LocationPreferenceController.java | 50 ++++++++++++-- .../LocationPreferenceControllerTest.java | 65 ++++++++++++++----- 3 files changed, 99 insertions(+), 23 deletions(-) diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 9a149c3cd2f..9d44c42c85b 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -175,6 +175,12 @@ public class SecuritySettings extends SettingsPreferenceFragment return MetricsEvent.SECURITY; } + @Override + public void onAttach(Context context) { + super.onAttach(context); + mLocationcontroller = new LocationPreferenceController(context, getLifecycle()); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -205,7 +211,6 @@ public class SecuritySettings extends SettingsPreferenceFragment mTrustAgentClickIntent = savedInstanceState.getParcelable(TRUST_AGENT_CLICK_INTENT); } - mLocationcontroller = new LocationPreferenceController(activity); mManageDeviceAdminPreferenceController = new ManageDeviceAdminPreferenceController(activity); mEnterprisePrivacyPreferenceController diff --git a/src/com/android/settings/location/LocationPreferenceController.java b/src/com/android/settings/location/LocationPreferenceController.java index 766ee472bf1..b90bc256217 100644 --- a/src/com/android/settings/location/LocationPreferenceController.java +++ b/src/com/android/settings/location/LocationPreferenceController.java @@ -15,20 +15,46 @@ */ package com.android.settings.location; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.location.LocationManager; import android.provider.Settings.Secure; +import android.support.annotation.VisibleForTesting; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.PreferenceController; +import com.android.settings.core.lifecycle.Lifecycle; +import com.android.settings.core.lifecycle.LifecycleObserver; +import com.android.settings.core.lifecycle.events.OnPause; +import com.android.settings.core.lifecycle.events.OnResume; -public class LocationPreferenceController extends PreferenceController { +public class LocationPreferenceController extends PreferenceController implements + LifecycleObserver, OnResume, OnPause { private static final String KEY_LOCATION = "location"; + private Context mContext; private Preference mPreference; - public LocationPreferenceController(Context context) { + @VisibleForTesting + BroadcastReceiver mLocationProvidersChangedReceiver; + + public LocationPreferenceController(Context context, Lifecycle lifecycle) { super(context); + mContext = context; + mLocationProvidersChangedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(LocationManager.PROVIDERS_CHANGED_ACTION)) { + updateSummary(); + } + } + }; + if (lifecycle != null) { + lifecycle.addObserver(this); + } } @Override @@ -37,6 +63,21 @@ public class LocationPreferenceController extends PreferenceController { mPreference = screen.findPreference(KEY_LOCATION); } + @Override + public void onResume() { + if (mLocationProvidersChangedReceiver != null) { + mContext.registerReceiver(mLocationProvidersChangedReceiver, new IntentFilter( + LocationManager.PROVIDERS_CHANGED_ACTION)); + } + } + + @Override + public void onPause() { + if (mLocationProvidersChangedReceiver != null) { + mContext.unregisterReceiver(mLocationProvidersChangedReceiver); + } + } + @Override public void updateState(Preference preference) { preference.setSummary(getLocationSummary(mContext)); @@ -58,10 +99,10 @@ public class LocationPreferenceController extends PreferenceController { public static String getLocationSummary(Context context) { int mode = Secure.getInt(context.getContentResolver(), - Secure.LOCATION_MODE, Secure.LOCATION_MODE_OFF); + Secure.LOCATION_MODE, Secure.LOCATION_MODE_OFF); if (mode != Secure.LOCATION_MODE_OFF) { return context.getString(R.string.location_on_summary, - context.getString(getLocationString(mode))); + context.getString(getLocationString(mode))); } return context.getString(R.string.location_off_summary); } @@ -79,5 +120,4 @@ public class LocationPreferenceController extends PreferenceController { } return 0; } - } diff --git a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java index 2e001695dfb..882a9abede7 100644 --- a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java @@ -15,7 +15,11 @@ */ package com.android.settings.location; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.location.LocationManager; import android.provider.Settings.Secure; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; @@ -24,6 +28,7 @@ import com.android.settings.R; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; +import com.android.settings.core.lifecycle.Lifecycle; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,10 +36,11 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowApplication; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -46,6 +52,7 @@ public class LocationPreferenceControllerTest { @Mock private PreferenceScreen mScreen; + private Lifecycle mLifecycle; private LocationPreferenceController mController; @Mock(answer = Answers.RETURNS_DEEP_STUBS) @@ -54,7 +61,8 @@ public class LocationPreferenceControllerTest { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mController = new LocationPreferenceController(mContext); + mLifecycle = new Lifecycle(); + mController = new LocationPreferenceController(mContext, mLifecycle); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); } @@ -81,52 +89,75 @@ public class LocationPreferenceControllerTest { @Test public void getLocationSummary_locationOff_shouldSetSummaryOff() { Secure.putInt(mContext.getContentResolver(), - Secure.LOCATION_MODE, Secure.LOCATION_MODE_OFF); + Secure.LOCATION_MODE, Secure.LOCATION_MODE_OFF); assertThat(mController.getLocationSummary(mContext)).isEqualTo( - mContext.getString(R.string.location_off_summary)); + mContext.getString(R.string.location_off_summary)); } @Test public void getLocationSummary_sensorsOnly_shouldSetSummarySensorsOnly() { Secure.putInt(mContext.getContentResolver(), - Secure.LOCATION_MODE, Secure.LOCATION_MODE_SENSORS_ONLY); + Secure.LOCATION_MODE, Secure.LOCATION_MODE_SENSORS_ONLY); assertThat(mController.getLocationSummary(mContext)).isEqualTo( - mContext.getString(R.string.location_on_summary, - mContext.getString(R.string.location_mode_sensors_only_title))); + mContext.getString(R.string.location_on_summary, + mContext.getString(R.string.location_mode_sensors_only_title))); } @Test public void getLocationSummary_highAccuracy_shouldSetSummarHighAccuracy() { Secure.putInt(mContext.getContentResolver(), - Secure.LOCATION_MODE, Secure.LOCATION_MODE_HIGH_ACCURACY); + Secure.LOCATION_MODE, Secure.LOCATION_MODE_HIGH_ACCURACY); assertThat(mController.getLocationSummary(mContext)).isEqualTo( - mContext.getString(R.string.location_on_summary, - mContext.getString(R.string.location_mode_high_accuracy_title))); + mContext.getString(R.string.location_on_summary, + mContext.getString(R.string.location_mode_high_accuracy_title))); } @Test public void getLocationSummary_batterySaving_shouldSetSummaryBatterySaving() { Secure.putInt(mContext.getContentResolver(), - Secure.LOCATION_MODE, Secure.LOCATION_MODE_BATTERY_SAVING); + Secure.LOCATION_MODE, Secure.LOCATION_MODE_BATTERY_SAVING); assertThat(mController.getLocationSummary(mContext)).isEqualTo( - mContext.getString(R.string.location_on_summary, - mContext.getString(R.string.location_mode_battery_saving_title))); + mContext.getString(R.string.location_on_summary, + mContext.getString(R.string.location_mode_battery_saving_title))); } @Test public void getLocationString_shouldCorrectString() { assertThat(mController.getLocationString(Secure.LOCATION_MODE_OFF)).isEqualTo( - R.string.location_mode_location_off_title); + R.string.location_mode_location_off_title); assertThat(mController.getLocationString(Secure.LOCATION_MODE_SENSORS_ONLY)).isEqualTo( - R.string.location_mode_sensors_only_title); + R.string.location_mode_sensors_only_title); assertThat(mController.getLocationString(Secure.LOCATION_MODE_BATTERY_SAVING)).isEqualTo( - R.string.location_mode_battery_saving_title); + R.string.location_mode_battery_saving_title); assertThat(mController.getLocationString(Secure.LOCATION_MODE_HIGH_ACCURACY)).isEqualTo( - R.string.location_mode_high_accuracy_title); + R.string.location_mode_high_accuracy_title); } + @Test + public void onResume_shouldRegisterObserver() { + mLifecycle.onResume(); + verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); + } + + @Test + public void onPause_shouldUnregisterObserver() { + mLifecycle.onPause(); + verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); + } + + @Test + public void locationProvidersChangedReceiver_updatesPreferenceSummary() { + mController.displayPreference(mScreen); + mController.onResume(); + + mController.mLocationProvidersChangedReceiver.onReceive( + mContext, + new Intent().setAction(LocationManager.PROVIDERS_CHANGED_ACTION)); + + verify(mPreference).setSummary(any()); + } }