From 1ee13fd38693835ee6ee138e2d798076d7753224 Mon Sep 17 00:00:00 2001 From: Daniel Nishi Date: Tue, 21 Mar 2017 14:13:39 -0700 Subject: [PATCH] Update the automatic storage management preferences. This updates this page to match the newer mocks. The changes include: * Changing the toggle from a switch to a switch bar. * Removing the Deletion Helper flow from the screen. * Unit testing the previously untested functionality. Change-Id: I35eb1e065c9acfbf32a64d659d35e18034025472 Fixes: 36486021 Test: Robotest --- .../automatic_storage_management_settings.xml | 30 +--- .../AutomaticStorageManagerSettings.java | 130 ++++++++---------- ...aticStorageManagerSwitchBarController.java | 85 ++++++++++++ ...StorageManagerSwitchBarControllerTest.java | 124 +++++++++++++++++ 4 files changed, 275 insertions(+), 94 deletions(-) create mode 100644 src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java create mode 100644 tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java diff --git a/res/xml/automatic_storage_management_settings.xml b/res/xml/automatic_storage_management_settings.xml index 73d708d9308..1428741e8cf 100644 --- a/res/xml/automatic_storage_management_settings.xml +++ b/res/xml/automatic_storage_management_settings.xml @@ -18,38 +18,18 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/automatic_storage_manager_settings" > - - - - - - - - - - + settings:allowDividerBelow="true" /> - - + android:key="freed_bytes" + android:persistent="false" + android:selectable="false" + settings:allowDividerAbove="true" /> \ No newline at end of file diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java index 4d4cfe8b42d..adf293832c5 100644 --- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java +++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java @@ -17,44 +17,39 @@ package com.android.settings.deletionhelper; import android.app.Activity; -import android.app.AlertDialog; -import android.app.FragmentManager; import android.content.ContentResolver; -import android.content.Intent; import android.os.Bundle; -import android.os.SystemProperties; -import android.os.storage.StorageManager; import android.provider.Settings; -import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.DropDownPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.text.format.DateUtils; import android.text.format.Formatter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; +import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.widget.SwitchBar; /** * AutomaticStorageManagerSettings is the Settings screen for configuration and management of the * automatic storage manager. */ -public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment implements - OnPreferenceChangeListener, Preference.OnPreferenceClickListener { - public static final int DEFAULT_DAYS_TO_RETAIN = 90; - +public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment + implements OnPreferenceChangeListener { private static final String KEY_DAYS = "days"; - private static final String KEY_DELETION_HELPER = "deletion_helper"; private static final String KEY_FREED = "freed_bytes"; - private static final String KEY_STORAGE_MANAGER_SWITCH = "storage_manager_active"; private static final String STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY = "ro.storage_manager.enabled"; + private AutomaticStorageManagerSwitchBarController mSwitchController; private DropDownPreference mDaysToRetain; private Preference mFreedBytes; - private Preference mDeletionHelper; - private SwitchPreference mStorageManagerSwitch; + private SwitchBar mSwitchBar; @Override public void onCreate(Bundle savedInstanceState) { @@ -63,19 +58,21 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment } @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + + initializeDaysToRetainPreference(); + initializeFreedBytesPreference(); + initializeSwitchBar(); + + return view; + } + + private void initializeDaysToRetainPreference() { mDaysToRetain = (DropDownPreference) findPreference(KEY_DAYS); mDaysToRetain.setOnPreferenceChangeListener(this); - mFreedBytes = findPreference(KEY_FREED); - - mDeletionHelper = findPreference(KEY_DELETION_HELPER); - mDeletionHelper.setOnPreferenceClickListener(this); - - mStorageManagerSwitch = (SwitchPreference) findPreference(KEY_STORAGE_MANAGER_SWITCH); - mStorageManagerSwitch.setOnPreferenceChangeListener(this); - ContentResolver cr = getContentResolver(); int photosDaysToRetain = Settings.Secure.getInt(cr, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, @@ -83,7 +80,24 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment String[] stringValues = getResources().getStringArray(R.array.automatic_storage_management_days_values); mDaysToRetain.setValue(stringValues[daysValueToIndex(photosDaysToRetain, stringValues)]); + } + private void initializeSwitchBar() { + final SettingsActivity activity = (SettingsActivity) getActivity(); + mSwitchBar = activity.getSwitchBar(); + mSwitchBar.show(); + mSwitchController = + new AutomaticStorageManagerSwitchBarController( + getContext(), + mSwitchBar, + mMetricsFeatureProvider, + mDaysToRetain, + getFragmentManager()); + } + + private void initializeFreedBytesPreference() { + ContentResolver cr = getContentResolver(); + mFreedBytes = findPreference(KEY_FREED); long freedBytes = Settings.Secure.getLong(cr, Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED, 0); @@ -93,11 +107,13 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment if (freedBytes == 0 || lastRunMillis == 0) { mFreedBytes.setVisible(false); } else { - Activity activity = getActivity(); - mFreedBytes.setSummary(activity.getString( - R.string.automatic_storage_manager_freed_bytes, - Formatter.formatFileSize(activity, freedBytes), - DateUtils.formatDateTime(activity, lastRunMillis, DateUtils.FORMAT_SHOW_DATE))); + final Activity activity = getActivity(); + mFreedBytes.setSummary( + activity.getString( + R.string.automatic_storage_manager_freed_bytes, + Formatter.formatFileSize(activity, freedBytes), + DateUtils.formatDateTime( + activity, lastRunMillis, DateUtils.FORMAT_SHOW_DATE))); } } @@ -107,31 +123,27 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment boolean isStorageManagerChecked = Settings.Secure.getInt(getContentResolver(), Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, 0) != 0; - mStorageManagerSwitch.setChecked(isStorageManagerChecked); + // Using the setCheckedInternal means the checked status won't propagate through the + // listeners -- this will prevent us from accidentally causing a metrics event on resume. + mSwitchBar.setCheckedInternal(isStorageManagerChecked); mDaysToRetain.setEnabled(isStorageManagerChecked); } + @Override + public void onDestroyView() { + super.onDestroyView(); + + mSwitchBar.hide(); + mSwitchController.tearDown(); + } + @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - switch (preference.getKey()) { - case KEY_STORAGE_MANAGER_SWITCH: - boolean storageManagerChecked = (boolean) newValue; - mMetricsFeatureProvider.action(getContext(), - MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER, storageManagerChecked); - mDaysToRetain.setEnabled(storageManagerChecked); - Settings.Secure.putInt(getContentResolver(), - Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, - storageManagerChecked ? 1 : 0); - // Only show a warning if enabling. - if (storageManagerChecked) { - maybeShowWarning(); - } - break; - case KEY_DAYS: - Settings.Secure.putInt(getContentResolver(), - Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, - Integer.parseInt((String) newValue)); - break; + if (KEY_DAYS.equals(preference.getKey())) { + Settings.Secure.putInt( + getContentResolver(), + Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, + Integer.parseInt((String) newValue)); } return true; } @@ -141,15 +153,6 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment return MetricsEvent.STORAGE_MANAGER_SETTINGS; } - @Override - public boolean onPreferenceClick(Preference preference) { - if (KEY_DELETION_HELPER.equals(preference.getKey())) { - Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); - getContext().startActivity(intent); - } - return true; - } - @Override protected int getHelpResource() { return R.string.help_uri_storage; @@ -164,15 +167,4 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment } return indices.length - 1; } - - private void maybeShowWarning() { - // If the storage manager is on by default, we can use the normal message. - boolean warningUnneeded = SystemProperties.getBoolean( - STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY, false); - if (warningUnneeded) { - return; - } - ActivationWarningFragment fragment = ActivationWarningFragment.newInstance(); - fragment.show(getFragmentManager(), ActivationWarningFragment.TAG); - } } diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java new file mode 100644 index 00000000000..a6481022a64 --- /dev/null +++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarController.java @@ -0,0 +1,85 @@ +/* + * 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.deletionhelper; + +import android.app.FragmentManager; +import android.content.Context; +import android.os.SystemProperties; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.widget.Switch; + +import com.android.internal.util.Preconditions; +import com.android.settings.core.instrumentation.MetricsFeatureProvider; +import com.android.settings.widget.SwitchBar; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + +/** Handles the logic for flipping the storage management toggle on a {@link SwitchBar}. */ +public class AutomaticStorageManagerSwitchBarController + implements SwitchBar.OnSwitchChangeListener { + private static final String STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY = + "ro.storage_manager.enabled"; + + private Context mContext; + private SwitchBar mSwitchBar; + private MetricsFeatureProvider mMetrics; + private Preference mDaysToRetainPreference; + private FragmentManager mFragmentManager; + + public AutomaticStorageManagerSwitchBarController( + Context context, + SwitchBar switchBar, + MetricsFeatureProvider metrics, + Preference daysToRetainPreference, + FragmentManager fragmentManager) { + mContext = Preconditions.checkNotNull(context); + mSwitchBar = Preconditions.checkNotNull(switchBar); + mMetrics = Preconditions.checkNotNull(metrics); + mDaysToRetainPreference = Preconditions.checkNotNull(daysToRetainPreference); + mFragmentManager = Preconditions.checkNotNull(fragmentManager); + + mSwitchBar.addOnSwitchChangeListener(this); + } + + @Override + public void onSwitchChanged(Switch switchView, boolean isChecked) { + mMetrics.action(mContext, MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER, isChecked); + mDaysToRetainPreference.setEnabled(isChecked); + Settings.Secure.putInt( + mContext.getContentResolver(), + Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED, + isChecked ? 1 : 0); + // Only show a warning if enabling. + if (isChecked) { + maybeShowWarning(); + } + } + + /** Unregisters the controller from listening to further events. */ + public void tearDown() { + mSwitchBar.removeOnSwitchChangeListener(this); + } + + private void maybeShowWarning() { + // If the storage manager is on by default, we don't need to show the additional dialog. + if (SystemProperties.getBoolean(STORAGE_MANAGER_ENABLED_BY_DEFAULT_PROPERTY, false)) { + return; + } + ActivationWarningFragment fragment = ActivationWarningFragment.newInstance(); + fragment.show(mFragmentManager, ActivationWarningFragment.TAG); + } +} diff --git a/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java new file mode 100644 index 00000000000..b4f5f3d778c --- /dev/null +++ b/tests/robotests/src/com/android/settings/deletionhelper/AutomaticStorageManagerSwitchBarControllerTest.java @@ -0,0 +1,124 @@ +/* + * 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.deletionhelper; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.app.Fragment; +import android.app.FragmentManager; +import android.content.Context; +import android.support.v7.preference.Preference; + +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.core.instrumentation.MetricsFeatureProvider; +import com.android.settings.overlay.FeatureFactory; +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; +import com.android.settings.widget.SwitchBar; + +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.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class AutomaticStorageManagerSwitchBarControllerTest { + private Context mContext; + private SwitchBar mSwitchBar; + private MetricsFeatureProvider mMetricsFeatureProvider; + private Preference mPreference; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private FragmentManager mFragmentManager; + + private AutomaticStorageManagerSwitchBarController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = spy(RuntimeEnvironment.application); + mSwitchBar = new SwitchBar(mContext); + + Context fakeContextForFakeProvider = mock(Context.class, RETURNS_DEEP_STUBS); + FeatureFactory featureFactory = FakeFeatureFactory.getFactory(fakeContextForFakeProvider); + mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); + mPreference = new Preference(mContext); + + mController = + new AutomaticStorageManagerSwitchBarController( + mContext, + mSwitchBar, + mMetricsFeatureProvider, + mPreference, + mFragmentManager); + } + + @Test + public void onSwitchChanged_false_recordsAMetric() { + mController.onSwitchChanged(null, false); + + verify(mMetricsFeatureProvider) + .action( + eq(mContext), + eq(MetricsProto.MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER), + eq(false)); + } + + @Test + public void onSwitchChanged_true_recordsAMetric() { + mController.onSwitchChanged(null, true); + + verify(mMetricsFeatureProvider) + .action( + eq(mContext), + eq(MetricsProto.MetricsEvent.ACTION_TOGGLE_STORAGE_MANAGER), + eq(true)); + } + + @Test + public void onSwitchChanged_showWarningFragmentIfNotEnabledByDefault() { + mController.onSwitchChanged(null, true); + + verify(mFragmentManager.beginTransaction()) + .add(any(Fragment.class), eq(ActivationWarningFragment.TAG)); + } + + @Config(shadows = {SettingsShadowSystemProperties.class}) + @Test + public void onSwitchChange_doNotShowWarningFragmentIfEnabledByDefault() { + SettingsShadowSystemProperties.set("ro.storage_manager.enabled", "true"); + + mController.onSwitchChanged(null, true); + + verify(mFragmentManager.beginTransaction(), never()) + .add(any(Fragment.class), eq(ActivationWarningFragment.TAG)); + } +}