OSDN Git Service

Add storage_summary_donut above ProfileSelectStorageFragment
authorRaff Tsai <rafftsai@google.com>
Fri, 15 Nov 2019 03:02:25 +0000 (11:02 +0800)
committerRaff Tsai <rafftsai@google.com>
Mon, 18 Nov 2019 10:18:29 +0000 (18:18 +0800)
- Modify ProfileSelectFragment to support add preference xml in the
top, and tabLayout below the preferences. Base preference layout is
dummy_preference_screen.xml which contains no preference.
ProfileSelectStorageFragment contains StorageSummaryDonutPreference
above the tabLayout.
- Make StorageSummaryDonutPreferenceController self workable without
StorageDashboardFragment dependence.
- Rename inactive_apps.xml to dummy_preference_screen.xml
- Move ShadowPrivateStorageInfo from LowStorageSliceTest

Bug: 141601408
Test: manual
Change-Id: Ide12840dc81bb104f328e230ecda5d35bba01d7a

18 files changed:
res/xml/dummy_preference_screen.xml [moved from res/xml/inactive_apps.xml with 86% similarity]
res/xml/storage_dashboard_fragment.xml
res/xml/storage_summary_donut.xml [new file with mode: 0644]
src/com/android/settings/Utils.java
src/com/android/settings/applications/manageapplications/ManageApplications.java
src/com/android/settings/dashboard/profileselector/ProfileSelectFragment.java
src/com/android/settings/dashboard/profileselector/ProfileSelectManageApplications.java
src/com/android/settings/dashboard/profileselector/ProfileSelectStorageFragment.java
src/com/android/settings/deviceinfo/StorageDashboardFragment.java
src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
src/com/android/settings/fuelgauge/InactiveApps.java
src/com/android/settings/search/actionbar/SearchMenuController.java
tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
tests/robotests/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceControllerTest.java
tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java
tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java
tests/robotests/src/com/android/settings/testutils/shadow/ShadowPrivateStorageInfo.java [new file with mode: 0644]

similarity index 86%
rename from res/xml/inactive_apps.xml
rename to res/xml/dummy_preference_screen.xml
index 6f93bdb..4ffa916 100644 (file)
@@ -15,8 +15,7 @@
 -->
 
 <PreferenceScreen
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:title="@string/inactive_apps_title">
-
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    settings:searchable="false">
 </PreferenceScreen>
 
index 63ce90b..66447cd 100644 (file)
@@ -22,7 +22,9 @@
     android:orderingFromXml="false">
     <com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
         android:key="pref_summary"
-        android:order="0" />
+        android:order="0"
+        settings:searchable="false"
+        settings:controller="com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController"/>
     <com.android.settings.widget.MasterSwitchPreference
         android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings"
         android:key="toggle_asm"
diff --git a/res/xml/storage_summary_donut.xml b/res/xml/storage_summary_donut.xml
new file mode 100644 (file)
index 0000000..be95cf8
--- /dev/null
@@ -0,0 +1,28 @@
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:key="storage_dashboard_screen"
+    android:title="@string/storage_settings"
+    android:orderingFromXml="false">
+    <com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
+        android:key="pref_summary"
+        android:order="0"
+        settings:searchable="false"
+        settings:controller="com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController"/>
+</PreferenceScreen>
\ No newline at end of file
index 65d0c82..b5a1539 100644 (file)
@@ -21,9 +21,6 @@ import static android.content.Intent.EXTRA_USER_ID;
 import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
 import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
 
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_PERSONAL_ONLY;
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_WORK_ONLY;
-
 import android.annotation.Nullable;
 import android.app.ActionBar;
 import android.app.Activity;
@@ -106,6 +103,7 @@ import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.dashboard.profileselector.ProfileFragmentBridge;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settingslib.widget.ActionBarShadowController;
 
@@ -1061,12 +1059,14 @@ public final class Utils extends com.android.settingslib.Utils {
      */
     public static Fragment getTargetFragment(Activity activity, String fragmentName, Bundle args) {
         Fragment f = null;
-        final boolean isWorkOnly = args == null ? false : args.getBoolean(EXTRA_WORK_ONLY);
-        final boolean isPersonalOnly = args == null ? false : args.getBoolean(EXTRA_PERSONAL_ONLY);
+        final boolean isPersonal = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+                == ProfileSelectFragment.PERSONAL : false;
+        final boolean isWork = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+                == ProfileSelectFragment.WORK : false;
         if (FeatureFlagUtils.isEnabled(activity, FeatureFlags.PERSONAL_WORK_PROFILE)
                 && UserManager.get(activity).getUserProfiles().size() > 1
                 && ProfileFragmentBridge.FRAGMENT_MAP.get(fragmentName) != null
-                && !isWorkOnly && !isPersonalOnly) {
+                && !isWork && !isPersonal) {
             f = Fragment.instantiate(activity, ProfileFragmentBridge.FRAGMENT_MAP.get(fragmentName),
                     args);
         } else {
index 01289f2..1906a2d 100644 (file)
@@ -29,6 +29,7 @@ import static com.android.settings.applications.manageapplications.AppFilterRegi
 import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_POWER_WHITELIST_ALL;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_RECENT;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WORK;
+import static com.android.settings.search.actionbar.SearchMenuController.MENU_SEARCH;
 
 import android.annotation.Nullable;
 import android.annotation.StringRes;
@@ -99,6 +100,7 @@ import com.android.settings.applications.appinfo.ExternalSourcesDetails;
 import com.android.settings.applications.appinfo.WriteSettingsDetails;
 import com.android.settings.core.InstrumentedFragment;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.fuelgauge.HighPowerDetail;
 import com.android.settings.notification.AppNotificationSettings;
 import com.android.settings.notification.ConfigureNotificationSettings;
@@ -141,9 +143,7 @@ public class ManageApplications extends InstrumentedFragment
     public static final String EXTRA_VOLUME_UUID = "volumeUuid";
     public static final String EXTRA_VOLUME_NAME = "volumeName";
     public static final String EXTRA_STORAGE_TYPE = "storageType";
-    public static final String EXTRA_WORK_ONLY = "workProfileOnly";
     public static final String EXTRA_WORK_ID = "workId";
-    public static final String EXTRA_PERSONAL_ONLY = "personalOnly";
 
     private static final String EXTRA_SORT_ORDER = "sortOrder";
     private static final String EXTRA_SHOW_SYSTEM = "showSystem";
@@ -310,8 +310,10 @@ public class ManageApplications extends InstrumentedFragment
         }
         final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
         mFilter = appFilterRegistry.get(appFilterRegistry.getDefaultFilterType(mListType));
-        mIsPersonalOnly = args != null ? args.getBoolean(EXTRA_PERSONAL_ONLY) : false;
-        mIsWorkOnly = args != null ? args.getBoolean(EXTRA_WORK_ONLY) : false;
+        mIsPersonalOnly = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+                == ProfileSelectFragment.PERSONAL : false;
+        mIsWorkOnly = args != null ? args.getInt(ProfileSelectFragment.EXTRA_PROFILE)
+                == ProfileSelectFragment.WORK : false;
         mWorkUserId = args != null ? args.getInt(EXTRA_WORK_ID) : NO_USER_SPECIFIED;
         mExpandSearch = activity.getIntent().getBooleanExtra(EXTRA_EXPAND_SEARCH_VIEW, false);
 
@@ -696,6 +698,10 @@ public class ManageApplications extends InstrumentedFragment
         // Hide notification menu items, because sorting happens when filtering
         mOptionsMenu.findItem(R.id.sort_order_recent_notification).setVisible(false);
         mOptionsMenu.findItem(R.id.sort_order_frequent_notification).setVisible(false);
+        final MenuItem searchItem = mOptionsMenu.findItem(MENU_SEARCH);
+        if (searchItem != null) {
+            searchItem.setVisible(false);
+        }
     }
 
     @Override
index b7a1301..b8d4be1 100644 (file)
@@ -22,13 +22,15 @@ import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
 
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentStatePagerAdapter;
 import androidx.viewpager.widget.ViewPager;
 
 import com.android.settings.R;
-import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.dashboard.DashboardFragment;
 
 import com.google.android.material.tabs.TabLayout;
 
@@ -38,7 +40,9 @@ import java.lang.annotation.RetentionPolicy;
 /**
  * Base fragment class for profile settings.
  */
-public abstract class ProfileSelectFragment extends InstrumentedFragment {
+public abstract class ProfileSelectFragment extends DashboardFragment {
+
+    private static final String TAG = "ProfileSelectFragment";
 
     /**
      * Denotes the profile type.
@@ -63,16 +67,29 @@ public abstract class ProfileSelectFragment extends InstrumentedFragment {
      */
     public static final int ALL = PERSONAL | WORK;
 
-    private View mContentView;
+    /**
+     * Used in fragment argument and pass {@link ProfileType} to it
+     */
+    public static final String EXTRA_PROFILE = "profile";
+
+    private ViewGroup mContentView;
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
-        mContentView = inflater.inflate(R.layout.profile_select_tablayout, null /* root */);
-        final ViewPager viewPager = mContentView.findViewById(R.id.view_pager);
-        viewPager.setAdapter(new ViewPagerAdapter(this));
-        final TabLayout tabs = mContentView.findViewById(R.id.tabs);
+        mContentView = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
+
+        final View tabContainer = mContentView.findViewById(R.id.tab_container);
+        final ViewPager viewPager = tabContainer.findViewById(R.id.view_pager);
+        viewPager.setAdapter(new ProfileSelectFragment.ViewPagerAdapter(this));
+        final TabLayout tabs = tabContainer.findViewById(R.id.tabs);
         tabs.setupWithViewPager(viewPager);
+        tabContainer.setVisibility(View.VISIBLE);
+
+        final FrameLayout listContainer = mContentView.findViewById(android.R.id.list_container);
+        listContainer.setLayoutParams(new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT));
         return mContentView;
     }
 
@@ -87,13 +104,23 @@ public abstract class ProfileSelectFragment extends InstrumentedFragment {
      */
     public abstract Fragment[] getFragments();
 
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.dummy_preference_screen;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
     static class ViewPagerAdapter extends FragmentStatePagerAdapter {
 
         private final Fragment[] mChildFragments;
         private final Context mContext;
 
         ViewPagerAdapter(ProfileSelectFragment fragment) {
-            super(fragment.getActivity().getSupportFragmentManager());
+            super(fragment.getChildFragmentManager());
             mContext = fragment.getContext();
             mChildFragments = fragment.getFragments();
         }
index 7290258..8a9e4f8 100644 (file)
@@ -16,9 +16,6 @@
 
 package com.android.settings.dashboard.profileselector;
 
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_PERSONAL_ONLY;
-import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_WORK_ONLY;
-
 import android.os.Bundle;
 
 import androidx.fragment.app.Fragment;
@@ -33,12 +30,12 @@ public class ProfileSelectManageApplications extends ProfileSelectFragment {
     @Override
     public Fragment[] getFragments() {
         final Bundle workOnly = new Bundle();
-        workOnly.putBoolean(EXTRA_WORK_ONLY, true);
+        workOnly.putInt(EXTRA_PROFILE, ProfileSelectFragment.WORK);
         final Fragment workFragment = new ManageApplications();
         workFragment.setArguments(workOnly);
 
         final Bundle personalOnly = new Bundle();
-        personalOnly.putBoolean(EXTRA_PERSONAL_ONLY, true);
+        personalOnly.putInt(EXTRA_PROFILE, ProfileSelectFragment.PERSONAL);
         final Fragment personalFragment = new ManageApplications();
         personalFragment.setArguments(personalOnly);
         return new Fragment[]{
index c7e4fd8..fccabb5 100644 (file)
@@ -23,6 +23,7 @@ import android.os.storage.VolumeInfo;
 
 import androidx.fragment.app.Fragment;
 
+import com.android.settings.R;
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.deviceinfo.StorageProfileFragment;
 
@@ -35,6 +36,7 @@ public class ProfileSelectStorageFragment extends ProfileSelectFragment {
 
         final Bundle storageBundle = new Bundle();
         storageBundle.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL);
+        storageBundle.putInt(EXTRA_PROFILE, ProfileSelectFragment.PERSONAL);
 
         final Fragment storageDashboardFragment = new StorageDashboardFragment();
         storageDashboardFragment.setArguments(storageBundle);
@@ -46,7 +48,6 @@ public class ProfileSelectStorageFragment extends ProfileSelectFragment {
                 break;
             }
         }
-        // TODO(b/143330969): Need to think about more profile users case
         if (targetUser != null) {
             storageBundle.putInt(StorageProfileFragment.USER_ID_EXTRA, targetUser.id);
         }
@@ -58,5 +59,10 @@ public class ProfileSelectStorageFragment extends ProfileSelectFragment {
                 storageProfileFragment
         };
     }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.storage_summary_donut;
+    }
 }
 
index 0e53333..b36ad43 100644 (file)
@@ -33,16 +33,17 @@ import android.view.View;
 import androidx.annotation.VisibleForTesting;
 import androidx.loader.app.LoaderManager;
 import androidx.loader.content.Loader;
+import androidx.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
 import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
 import com.android.settings.deviceinfo.storage.SecondaryUserController;
 import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
 import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
-import com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController;
 import com.android.settings.deviceinfo.storage.UserIconLoader;
 import com.android.settings.deviceinfo.storage.VolumeSizesLoader;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -62,6 +63,7 @@ public class StorageDashboardFragment extends DashboardFragment
         implements
         LoaderManager.LoaderCallbacks<SparseArray<StorageAsyncLoader.AppsStorageResult>> {
     private static final String TAG = "StorageDashboardFrag";
+    private static final String SUMMARY_PREF_KEY = "pref_summary";
     private static final int STORAGE_JOB_ID = 0;
     private static final int ICON_JOB_ID = 1;
     private static final int VOLUME_SIZE_JOB_ID = 2;
@@ -71,10 +73,10 @@ public class StorageDashboardFragment extends DashboardFragment
     private SparseArray<StorageAsyncLoader.AppsStorageResult> mAppsResult;
     private CachedStorageValuesHelper mCachedStorageValuesHelper;
 
-    private StorageSummaryDonutPreferenceController mSummaryController;
     private StorageItemPreferenceController mPreferenceController;
     private PrivateVolumeOptionMenuController mOptionMenuController;
     private List<AbstractPreferenceController> mSecondaryUsers;
+    private boolean mPersonalOnly;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -84,12 +86,19 @@ public class StorageDashboardFragment extends DashboardFragment
         final Activity activity = getActivity();
         StorageManager sm = activity.getSystemService(StorageManager.class);
         mVolume = Utils.maybeInitializeVolume(sm, getArguments());
+        mPersonalOnly = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE)
+                == ProfileSelectFragment.PERSONAL;
         if (mVolume == null) {
             activity.finish();
             return;
         }
-
         initializeOptionsMenu(activity);
+        if (mPersonalOnly) {
+            final Preference summary = getPreferenceScreen().findPreference(SUMMARY_PREF_KEY);
+            if (summary != null) {
+                summary.setVisible(false);
+            }
+        }
     }
 
     @Override
@@ -119,7 +128,6 @@ public class StorageDashboardFragment extends DashboardFragment
                 null /* header view */)
                 .setRecyclerView(getListView(), getSettingsLifecycle())
                 .styleActionBar(activity);
-
     }
 
     @Override
@@ -140,7 +148,6 @@ public class StorageDashboardFragment extends DashboardFragment
         boolean stopLoading = false;
         if (mStorageInfo != null) {
             long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
-            mSummaryController.updateBytes(privateUsedBytes, mStorageInfo.totalBytes);
             mPreferenceController.setVolume(mVolume);
             mPreferenceController.setUsedSize(privateUsedBytes);
             mPreferenceController.setTotalSize(mStorageInfo.totalBytes);
@@ -187,8 +194,6 @@ public class StorageDashboardFragment extends DashboardFragment
     @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        mSummaryController = new StorageSummaryDonutPreferenceController(context);
-        controllers.add(mSummaryController);
 
         StorageManager sm = context.getSystemService(StorageManager.class);
         mPreferenceController = new StorageItemPreferenceController(context, this,
@@ -241,7 +246,6 @@ public class StorageDashboardFragment extends DashboardFragment
                     final StorageManager sm = context.getSystemService(StorageManager.class);
                     final UserManager userManager = context.getSystemService(UserManager.class);
                     final List<AbstractPreferenceController> controllers = new ArrayList<>();
-                    controllers.add(new StorageSummaryDonutPreferenceController(context));
                     controllers.add(new StorageItemPreferenceController(context, null /* host */,
                             null /* volume */, new StorageManagerVolumeProvider(sm)));
                     controllers.addAll(SecondaryUserController.getSecondaryUserControllers(
index 31898d1..26039fb 100644 (file)
@@ -41,6 +41,7 @@ import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.deviceinfo.PrivateVolumeSettings.SystemInfoFragment;
 import com.android.settings.deviceinfo.StorageItemPreference;
 import com.android.settings.overlay.FeatureFactory;
@@ -392,14 +393,15 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
 
     private Bundle getWorkAnnotatedBundle(int additionalCapacity) {
         if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.PERSONAL_WORK_PROFILE)) {
-            final Bundle args = new Bundle(3 + additionalCapacity);
-            args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile);
+            final Bundle args = new Bundle(2 + additionalCapacity);
+            args.putInt(ProfileSelectFragment.EXTRA_PROFILE,
+                    mIsWorkProfile ? ProfileSelectFragment.WORK : ProfileSelectFragment.PERSONAL);
             args.putInt(ManageApplications.EXTRA_WORK_ID, mUserId);
-            args.putBoolean(ManageApplications.EXTRA_PERSONAL_ONLY, !mIsWorkProfile);
             return args;
         } else {
             final Bundle args = new Bundle(2 + additionalCapacity);
-            args.putBoolean(ManageApplications.EXTRA_WORK_ONLY, mIsWorkProfile);
+            args.putInt(ProfileSelectFragment.EXTRA_PROFILE,
+                    mIsWorkProfile ? ProfileSelectFragment.WORK : ProfileSelectFragment.ALL);
             args.putInt(ManageApplications.EXTRA_WORK_ID, mUserId);
             return args;
         }
index d450a2a..d8ee711 100644 (file)
@@ -17,6 +17,7 @@
 package com.android.settings.deviceinfo.storage;
 
 import android.content.Context;
+import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.text.TextUtils;
 import android.text.format.Formatter;
@@ -25,22 +26,29 @@ import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.deviceinfo.PrivateStorageInfo;
+import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
+import com.android.settingslib.utils.ThreadUtils;
+
+import java.text.NumberFormat;
 
 /**
- * StorgaeSummaryPreferenceController updates the donut storage summary preference to have the
+ * SummaryPreferenceController updates the donut storage summary preference to have the
  * correct sizes showing.
  */
-public class StorageSummaryDonutPreferenceController extends AbstractPreferenceController implements
-        PreferenceControllerMixin {
+public class StorageSummaryDonutPreferenceController extends BasePreferenceController {
     private long mUsedBytes;
     private long mTotalBytes;
     private StorageSummaryDonutPreference mSummary;
+    private final StorageManager mStorageManager;
+    private final StorageManagerVolumeProvider mStorageManagerVolumeProvider;
 
-    public StorageSummaryDonutPreferenceController(Context context) {
-        super(context);
+    public StorageSummaryDonutPreferenceController(Context context, String key) {
+        super(context, key);
+        mStorageManager = mContext.getSystemService(StorageManager.class);
+        mStorageManagerVolumeProvider = new StorageManagerVolumeProvider(mStorageManager);
     }
 
     /**
@@ -58,19 +66,31 @@ public class StorageSummaryDonutPreferenceController extends AbstractPreferenceC
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
-        mSummary = screen.findPreference("pref_summary");
+        mSummary = screen.findPreference(getPreferenceKey());
         mSummary.setEnabled(true);
+
+        ThreadUtils.postOnBackgroundThread(() -> {
+            final NumberFormat percentageFormat = NumberFormat.getPercentInstance();
+            final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo(
+                    mStorageManagerVolumeProvider);
+            final double privateUsedBytes = info.totalBytes - info.freeBytes;
+            mTotalBytes = info.totalBytes;
+            mUsedBytes = info.totalBytes - info.freeBytes;
+
+            ThreadUtils.postOnMainThread(() -> {
+                updateState(mSummary);
+            });
+        });
     }
 
     @Override
     public void updateState(Preference preference) {
         super.updateState(preference);
-        StorageSummaryDonutPreference summary = (StorageSummaryDonutPreference) preference;
-        summary.setTitle(convertUsedBytesToFormattedText(mContext, mUsedBytes));
-        summary.setSummary(mContext.getString(R.string.storage_volume_total,
+        mSummary.setTitle(convertUsedBytesToFormattedText(mContext, mUsedBytes));
+        mSummary.setSummary(mContext.getString(R.string.storage_volume_total,
                 Formatter.formatShortFileSize(mContext, mTotalBytes)));
-        summary.setPercent(mUsedBytes, mTotalBytes);
-        summary.setEnabled(true);
+        mSummary.setPercent(mUsedBytes, mTotalBytes);
+        mSummary.setEnabled(true);
     }
 
     /** Invalidates the data on the view and re-renders. */
@@ -81,13 +101,8 @@ public class StorageSummaryDonutPreferenceController extends AbstractPreferenceC
     }
 
     @Override
-    public boolean isAvailable() {
-        return true;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return "pref_summary";
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
     }
 
     /**
index 6c8a954..c386a7d 100644 (file)
@@ -67,7 +67,8 @@ public class InactiveApps extends SettingsPreferenceFragment
         super.onCreate(icicle);
 
         mUsageStats = getActivity().getSystemService(UsageStatsManager.class);
-        addPreferencesFromResource(R.xml.inactive_apps);
+        addPreferencesFromResource(R.xml.dummy_preference_screen);
+        getActivity().setTitle(R.string.inactive_apps_title);
     }
 
     @Override
index 0243c09..9e22bbf 100644 (file)
@@ -42,6 +42,7 @@ import com.google.android.setupcompat.util.WizardManagerHelper;
 public class SearchMenuController implements LifecycleObserver, OnCreateOptionsMenu {
 
     public static final String NEED_SEARCH_ICON_IN_ACTION_BAR = "need_search_icon_in_action_bar";
+    public static final int MENU_SEARCH = Menu.FIRST + 10;
 
     private final Fragment mHost;
     private final int mPageId;
@@ -80,7 +81,11 @@ public class SearchMenuController implements LifecycleObserver, OnCreateOptionsM
         if (arguments != null && !arguments.getBoolean(NEED_SEARCH_ICON_IN_ACTION_BAR, true)) {
             return;
         }
-        final MenuItem searchItem = menu.add(Menu.NONE, Menu.NONE, 0 /* order */,
+        // menu contains search item, skip it
+        if (menu.findItem(MENU_SEARCH) != null) {
+            return;
+        }
+        final MenuItem searchItem = menu.add(Menu.NONE, MENU_SEARCH, 0 /* order */,
                 R.string.search_menu);
         searchItem.setIcon(R.drawable.ic_search_24dp);
         searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
index 73fea77..32c706c 100644 (file)
 package com.android.settings.deviceinfo.storage;
 
 import static com.android.settings.applications.manageapplications.ManageApplications.EXTRA_WORK_ID;
-import static com.android.settings.applications.manageapplications.ManageApplications
-        .EXTRA_WORK_ONLY;
 import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -51,6 +49,7 @@ import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SubSettings;
 import com.android.settings.applications.manageapplications.ManageApplications;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settings.deviceinfo.PrivateVolumeSettings;
 import com.android.settings.deviceinfo.StorageItemPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -195,8 +194,8 @@ public class StorageItemPreferenceControllerTest {
                 .isEqualTo(R.string.apps_storage);
         assertThat(
                 intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
-                        .getBoolean(EXTRA_WORK_ONLY))
-                .isTrue();
+                        .getInt(ProfileSelectFragment.EXTRA_PROFILE))
+                .isEqualTo(ProfileSelectFragment.WORK);
         assertThat(
                 intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
                         .getInt(EXTRA_WORK_ID))
index 4f72318..cd6f082 100644 (file)
@@ -37,24 +37,30 @@ import android.view.View;
 import android.widget.Button;
 import android.widget.LinearLayout;
 
+import androidx.preference.PreferenceScreen;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.ShadowPrivateStorageInfo;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.deviceinfo.PrivateStorageInfo;
 import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
 
 import java.io.File;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowPrivateStorageInfo.class)
 public class StorageSummaryDonutPreferenceControllerTest {
 
     private Context mContext;
@@ -63,14 +69,18 @@ public class StorageSummaryDonutPreferenceControllerTest {
     private PreferenceViewHolder mHolder;
     private FakeFeatureFactory mFakeFeatureFactory;
     private MetricsFeatureProvider mMetricsFeatureProvider;
+    private PreferenceScreen mScreen;
 
     @Before
     public void setUp() throws Exception {
+        ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(10L, 100L));
         mContext = spy(Robolectric.setupActivity(Activity.class));
         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
         mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
-        mController = new StorageSummaryDonutPreferenceController(mContext);
+        mController = new StorageSummaryDonutPreferenceController(mContext, "key");
         mPreference = new StorageSummaryDonutPreference(mContext);
+        mScreen = spy(new PreferenceScreen(mContext, null));
+        when(mScreen.findPreference("key")).thenReturn(mPreference);
 
         LayoutInflater inflater = LayoutInflater.from(mContext);
         final View view =
@@ -79,10 +89,16 @@ public class StorageSummaryDonutPreferenceControllerTest {
         mHolder = PreferenceViewHolder.createInstanceForTests(view);
     }
 
+    @After
+    public void tearDown() {
+        ShadowPrivateStorageInfo.reset();
+    }
+
     @Test
     public void testEmpty() {
         final long totalSpace = 32 * GIGABYTE;
         final long usedSpace = 0;
+        mController.displayPreference(mScreen);
         mController.updateBytes(0, 32 * GIGABYTE);
         mController.updateState(mPreference);
 
@@ -98,6 +114,7 @@ public class StorageSummaryDonutPreferenceControllerTest {
     public void testTotalStorage() {
         final long totalSpace = KILOBYTE * 10;
         final long usedSpace = KILOBYTE;
+        mController.displayPreference(mScreen);
         mController.updateBytes(KILOBYTE, totalSpace);
         mController.updateState(mPreference);
 
@@ -121,6 +138,7 @@ public class StorageSummaryDonutPreferenceControllerTest {
         when(file.getTotalSpace()).thenReturn(totalSpace);
         when(file.getFreeSpace()).thenReturn(freeSpace);
         when(svp.getPrimaryStorageSize()).thenReturn(totalSpace);
+        mController.displayPreference(mScreen);
 
         mController.updateSizes(svp, volume);
         mController.updateState(mPreference);
index 99f2723..c8ec57a 100644 (file)
@@ -28,8 +28,8 @@ import androidx.slice.SliceProvider;
 import androidx.slice.widget.SliceLiveData;
 
 import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowPrivateStorageInfo;
 import com.android.settingslib.deviceinfo.PrivateStorageInfo;
-import com.android.settingslib.deviceinfo.StorageVolumeProvider;
 
 import org.junit.After;
 import org.junit.Before;
@@ -38,9 +38,6 @@ import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
 
 @RunWith(RobolectricTestRunner.class)
 public class LowStorageSliceTest {
@@ -104,26 +101,4 @@ public class LowStorageSliceTest {
 
         assertThat(slice.hasHint(HINT_ERROR)).isTrue();
     }
-
-    @Implements(PrivateStorageInfo.class)
-    public static class ShadowPrivateStorageInfo {
-
-        private static PrivateStorageInfo sPrivateStorageInfo = null;
-
-        @Resetter
-        public static void reset() {
-            sPrivateStorageInfo = null;
-        }
-
-        @Implementation
-        public static PrivateStorageInfo getPrivateStorageInfo(
-                StorageVolumeProvider storageVolumeProvider) {
-            return sPrivateStorageInfo;
-        }
-
-        private static void setPrivateStorageInfo(
-                PrivateStorageInfo privateStorageInfo) {
-            sPrivateStorageInfo = privateStorageInfo;
-        }
-    }
 }
\ No newline at end of file
index e2b896a..c646a93 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.settings.search.actionbar;
 
+import static com.android.settings.search.actionbar.SearchMenuController.MENU_SEARCH;
+
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -69,7 +71,7 @@ public class SearchMenuControllerTest {
         Global.putInt(mActivity.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
 
         when(mHost.getActivity()).thenReturn(mActivity);
-        when(mMenu.add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu))
+        when(mMenu.add(Menu.NONE, MENU_SEARCH, 0 /* order */, R.string.search_menu))
                 .thenReturn(mock(MenuItem.class));
     }
 
@@ -78,7 +80,7 @@ public class SearchMenuControllerTest {
         SearchMenuController.init(mHost);
         mHost.getSettingsLifecycle().onCreateOptionsMenu(mMenu, null /* inflater */);
 
-        verify(mMenu).add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu);
+        verify(mMenu).add(Menu.NONE, MENU_SEARCH, 0 /* order */, R.string.search_menu);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPrivateStorageInfo.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPrivateStorageInfo.java
new file mode 100644 (file)
index 0000000..1baf3cb
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.testutils.shadow;
+
+import com.android.settingslib.deviceinfo.PrivateStorageInfo;
+import com.android.settingslib.deviceinfo.StorageVolumeProvider;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(PrivateStorageInfo.class)
+public class ShadowPrivateStorageInfo {
+
+    private static PrivateStorageInfo sPrivateStorageInfo = null;
+
+    @Resetter
+    public static void reset() {
+        sPrivateStorageInfo = null;
+    }
+
+    @Implementation
+    protected static PrivateStorageInfo getPrivateStorageInfo(
+            StorageVolumeProvider storageVolumeProvider) {
+        return sPrivateStorageInfo;
+    }
+
+    public static void setPrivateStorageInfo(
+            PrivateStorageInfo privateStorageInfo) {
+        sPrivateStorageInfo = privateStorageInfo;
+    }
+}