Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7badf465 authored by Daniel Nishi's avatar Daniel Nishi Committed by Android (Google) Code Review
Browse files

Merge "Update the automatic storage management preferences." into oc-dev

parents abde1705 1ee13fd3
Loading
Loading
Loading
Loading
+5 −25
Original line number Diff line number Diff line
@@ -18,38 +18,18 @@
        xmlns:settings="http://schemas.android.com/apk/res-auto"
        android:title="@string/automatic_storage_manager_settings" >

    <PreferenceCategory
        android:key="automatic"
        android:title="@string/deletion_helper_automatic_title">

        <SwitchPreference
            android:key="storage_manager_active"
            android:title="@string/automatic_storage_manager_preference_title"
            android:summary="@string/automatic_storage_manager_text"/>

        <Preference
            android:key="freed_bytes"
            android:persistent="false"
            android:selectable="false" />

        <DropDownPreference
            android:key="days"
            android:summary="%s"
            android:title="@string/automatic_storage_manager_days_title"
            android:entries="@array/automatic_storage_management_days"
            android:entryValues="@array/automatic_storage_management_days_values"
            settings:allowDividerAbove="true" />

    </PreferenceCategory>

    <PreferenceCategory
        android:key="manual"
        android:title="@string/deletion_helper_manual_title">
            settings:allowDividerBelow="true" />

        <Preference
            android:key="deletion_helper"
            android:title="@string/deletion_helper_preference_title"/>

    </PreferenceCategory>
            android:key="freed_bytes"
            android:persistent="false"
            android:selectable="false"
            settings:allowDividerAbove="true" />

</PreferenceScreen>
 No newline at end of file
+60 −68
Original line number Diff line number Diff line
@@ -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,18 +58,20 @@ public class AutomaticStorageManagerSettings extends SettingsPreferenceFragment
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mDaysToRetain = (DropDownPreference) findPreference(KEY_DAYS);
        mDaysToRetain.setOnPreferenceChangeListener(this);
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);

        mFreedBytes = findPreference(KEY_FREED);
        initializeDaysToRetainPreference();
        initializeFreedBytesPreference();
        initializeSwitchBar();

        mDeletionHelper = findPreference(KEY_DELETION_HELPER);
        mDeletionHelper.setOnPreferenceClickListener(this);
        return view;
    }

        mStorageManagerSwitch = (SwitchPreference) findPreference(KEY_STORAGE_MANAGER_SWITCH);
        mStorageManagerSwitch.setOnPreferenceChangeListener(this);
    private void initializeDaysToRetainPreference() {
        mDaysToRetain = (DropDownPreference) findPreference(KEY_DAYS);
        mDaysToRetain.setOnPreferenceChangeListener(this);

        ContentResolver cr = getContentResolver();
        int photosDaysToRetain = Settings.Secure.getInt(cr,
@@ -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(
            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)));
                            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(),
        if (KEY_DAYS.equals(preference.getKey())) {
            Settings.Secure.putInt(
                    getContentResolver(),
                    Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
                    Integer.parseInt((String) newValue));
                break;
        }
        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);
    }
}
+85 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}
+124 −0
Original line number Diff line number Diff line
/*
 * 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));
    }
}