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

Commit 54306821 authored by Arc Wang's avatar Arc Wang
Browse files

Implements profile selection tab in Storage Settings

- StorageDashboardFragment and StorageItemPreferenceController works only
  for one profile per instance.
- StorageAsyncLoader loads for all users(profiles) and regards each user independent.
- SecondaryUserController will not load personal profile user in work profile tab.
- Cleanup some unused profile related files.

Bug: 174964885
Test: atest com.android.settings.deviceinfo
      atest com.android.settings.deviceinfo.storage
      make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.deviceinfo
      make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.deviceinfo.storage
Change-Id: I8361c29bc240c519c7261b19522c41439479c1c2
Merged-In: I8361c29bc240c519c7261b19522c41439479c1c2
parent 2097ca6a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -469,6 +469,19 @@ public final class Utils extends com.android.settingslib.Utils {
        return UserHandle.USER_NULL;
    }

    /** Returns user ID of current user, throws IllegalStateException if it's not available. */
    public static int getCurrentUserId(UserManager userManager, boolean isWorkProfile)
            throws IllegalStateException {
        if (isWorkProfile) {
            final UserHandle managedUserHandle = getManagedProfile(userManager);
            if (managedUserHandle == null) {
                throw new IllegalStateException("Work profile user ID is not available.");
            }
            return managedUserHandle.getIdentifier();
        }
        return UserHandle.myUserId();
    }

    /**
     * Returns the target user for a Settings activity.
     * <p>
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.util.ArrayMap;

import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.location.LocationServices;
import com.android.settings.location.RecentLocationAccessSeeAllFragment;

@@ -46,5 +47,7 @@ public class ProfileFragmentBridge {
                ProfileSelectRecentLocationAccessFragment.class.getName());
        FRAGMENT_MAP.put(LocationServices.class.getName(),
                ProfileSelectLocationServicesFragment.class.getName());
        FRAGMENT_MAP.put(StorageDashboardFragment.class.getName(),
                ProfileSelectStorageFragment.class.getName());
    }
}
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.dashboard.profileselector;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import com.android.settings.deviceinfo.StorageDashboardFragment;

/**
 * Storage Settings page for personal/managed profile.
 */
public class ProfileSelectStorageFragment extends ProfileSelectFragment {

    @Override
    public Fragment[] getFragments() {
        final Bundle workBundle = new Bundle();
        workBundle.putInt(EXTRA_PROFILE, ProfileType.WORK);
        final Fragment workFragment = new StorageDashboardFragment();
        workFragment.setArguments(workBundle);

        final Bundle personalBundle = new Bundle();
        personalBundle.putInt(EXTRA_PROFILE, ProfileType.PERSONAL);
        final Fragment personalFragment = new StorageDashboardFragment();
        personalFragment.setArguments(personalBundle);

        return new Fragment[] {
            personalFragment,
            workFragment
        };
    }
}
+21 −22
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ public class StorageDashboardFragment extends DashboardFragment
    private static final int VOLUME_SIZE_JOB_ID = 2;

    private StorageManager mStorageManager;
    private UserManager mUserManager;
    private final List<StorageEntry> mStorageEntries = new ArrayList<>();
    private StorageEntry mSelectedStorageEntry;
    private PrivateStorageInfo mStorageInfo;
@@ -96,7 +97,8 @@ public class StorageDashboardFragment extends DashboardFragment
    private StorageSelectionPreferenceController mStorageSelectionController;
    private StorageUsageProgressBarPreferenceController mStorageUsageProgressBarController;
    private List<AbstractPreferenceController> mSecondaryUsers;
    private boolean mPersonalOnly;
    private boolean mIsWorkProfile;
    private int mUserId;
    private Preference mFreeUpSpacePreference;

    private final StorageEventListener mStorageEventListener = new StorageEventListener() {
@@ -270,8 +272,6 @@ public class StorageDashboardFragment extends DashboardFragment

        final Activity activity = getActivity();
        mStorageManager = activity.getSystemService(StorageManager.class);
        mPersonalOnly = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE)
                == ProfileSelectFragment.ProfileType.PERSONAL;

        if (icicle == null) {
            final VolumeInfo specifiedVolumeInfo =
@@ -288,18 +288,19 @@ public class StorageDashboardFragment extends DashboardFragment
    }

    private void initializePreference() {
        if (mPersonalOnly) {
            final Preference summary = getPreferenceScreen().findPreference(SUMMARY_PREF_KEY);
            if (summary != null) {
                summary.setVisible(false);
            }
        }
        mFreeUpSpacePreference = getPreferenceScreen().findPreference(FREE_UP_SPACE_PREF_KEY);
        mFreeUpSpacePreference.setOnPreferenceClickListener(this);
    }

    @Override
    public void onAttach(Context context) {
        // These member variables are initialized befoer super.onAttach for
        // createPreferenceControllers to work correctly.
        mUserManager = context.getSystemService(UserManager.class);
        mIsWorkProfile = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE)
                == ProfileSelectFragment.ProfileType.WORK;
        mUserId = Utils.getCurrentUserId(mUserManager, mIsWorkProfile);

        super.onAttach(context);
        use(AutomaticStorageManagementSwitchPreferenceController.class).setFragmentManager(
                getFragmentManager());
@@ -396,7 +397,7 @@ public class StorageDashboardFragment extends DashboardFragment
        }

        if (mAppsResult != null) {
            mPreferenceController.onLoadFinished(mAppsResult, UserHandle.myUserId());
            mPreferenceController.onLoadFinished(mAppsResult, mUserId);
            updateSecondaryUserControllers(mSecondaryUsers, mAppsResult);
            stopLoading = true;
        }
@@ -427,14 +428,13 @@ public class StorageDashboardFragment extends DashboardFragment
    @Override
    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
        final List<AbstractPreferenceController> controllers = new ArrayList<>();

        StorageManager sm = context.getSystemService(StorageManager.class);
        mPreferenceController = new StorageItemPreferenceController(context, this,
                null /* volume */, new StorageManagerVolumeProvider(sm));
                null /* volume */, new StorageManagerVolumeProvider(sm), mIsWorkProfile);
        controllers.add(mPreferenceController);

        final UserManager userManager = context.getSystemService(UserManager.class);
        mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context, userManager);
        mSecondaryUsers = SecondaryUserController.getSecondaryUserControllers(context,
                mUserManager, mIsWorkProfile /* isWorkProfileOnly */);
        controllers.addAll(mSecondaryUsers);

        return controllers;
@@ -480,9 +480,10 @@ public class StorageDashboardFragment extends DashboardFragment
                    final UserManager userManager = context.getSystemService(UserManager.class);
                    final List<AbstractPreferenceController> controllers = new ArrayList<>();
                    controllers.add(new StorageItemPreferenceController(context, null /* host */,
                            null /* volume */, new StorageManagerVolumeProvider(sm)));
                            null /* volume */, new StorageManagerVolumeProvider(sm),
                            false /* isWorkProfile */));
                    controllers.addAll(SecondaryUserController.getSecondaryUserControllers(
                            context, userManager));
                            context, userManager, false /* isWorkProfileOnly */));
                    return controllers;
                }

@@ -492,7 +493,7 @@ public class StorageDashboardFragment extends DashboardFragment
    public Loader<SparseArray<StorageAsyncLoader.AppsStorageResult>> onCreateLoader(int id,
            Bundle args) {
        final Context context = getContext();
        return new StorageAsyncLoader(context, context.getSystemService(UserManager.class),
        return new StorageAsyncLoader(context, mUserManager,
                mSelectedStorageEntry.getFsUuid(),
                new StorageStatsSource(context),
                context.getPackageManager());
@@ -519,7 +520,7 @@ public class StorageDashboardFragment extends DashboardFragment
            metricsFeatureProvider.logClickedPreference(preference, getMetricsCategory());
            metricsFeatureProvider.action(context, SettingsEnums.STORAGE_FREE_UP_SPACE_NOW);
            final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
            context.startActivity(intent);
            context.startActivityAsUser(intent, new UserHandle(mUserId));
            return true;
        }
        return false;
@@ -574,16 +575,14 @@ public class StorageDashboardFragment extends DashboardFragment
    }

    private void initializeCacheProvider() {
        mCachedStorageValuesHelper =
                new CachedStorageValuesHelper(getContext(), UserHandle.myUserId());
        mCachedStorageValuesHelper = new CachedStorageValuesHelper(getContext(), mUserId);
        initializeCachedValues();
        onReceivedSizes();
    }

    private void maybeCacheFreshValues() {
        if (mStorageInfo != null && mAppsResult != null) {
            mCachedStorageValuesHelper.cacheResult(
                    mStorageInfo, mAppsResult.get(UserHandle.myUserId()));
            mCachedStorageValuesHelper.cacheResult(mStorageInfo, mAppsResult.get(mUserId));
        }
    }

+0 −138
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.deviceinfo;

import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.util.SparseArray;

import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader.AppsStorageResult;
import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;

import java.util.ArrayList;
import java.util.List;

/**
 * StorageProfileFragment is a fragment which shows the storage results for a profile of the
 * primary user.
 */
public class StorageProfileFragment extends DashboardFragment
        implements LoaderManager.LoaderCallbacks<SparseArray<AppsStorageResult>> {
    private static final String TAG = "StorageProfileFragment";
    public static final String USER_ID_EXTRA = "userId";
    private static final int APPS_JOB_ID = 0;

    private VolumeInfo mVolume;
    private int mUserId;
    private StorageItemPreferenceController mPreferenceController;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        final Bundle args = getArguments();

        // Initialize the storage sizes that we can quickly calc.
        final Context context = getActivity();
        final StorageManager sm = context.getSystemService(StorageManager.class);
        mVolume = Utils.maybeInitializeVolume(sm, args);
        if (mVolume == null) {
            getActivity().finish();
            return;
        }

        mPreferenceController.setVolume(mVolume);
        mUserId = args.getInt(USER_ID_EXTRA, UserHandle.myUserId());
        mPreferenceController.setUserId(UserHandle.of(mUserId));
    }

    @Override
    public void onResume() {
        super.onResume();
        getLoaderManager().initLoader(APPS_JOB_ID, Bundle.EMPTY, this);
    }

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.SETTINGS_STORAGE_PROFILE;
    }

    @Override
    protected String getLogTag() {
        return TAG;
    }

    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.storage_profile_fragment;
    }

    @Override
    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
        final List<AbstractPreferenceController> controllers = new ArrayList<>();
        final StorageManager sm = context.getSystemService(StorageManager.class);
        mPreferenceController =
                new StorageItemPreferenceController(
                        context,
                        this,
                        mVolume,
                        new StorageManagerVolumeProvider(sm),
                        /* isWorkProfile */ true);
        controllers.add(mPreferenceController);
        return controllers;
    }

    @Override
    public Loader<SparseArray<AppsStorageResult>> onCreateLoader(int id, Bundle args) {
        final Context context = getContext();
        return new StorageAsyncLoader(context,
                context.getSystemService(UserManager.class),
                mVolume.fsUuid,
                new StorageStatsSource(context),
                context.getPackageManager());
    }

    @Override
    public void onLoadFinished(Loader<SparseArray<AppsStorageResult>> loader,
            SparseArray<AppsStorageResult> result) {
        mPreferenceController.onLoadFinished(result, mUserId);
    }

    @Override
    public void onLoaderReset(Loader<SparseArray<AppsStorageResult>> loader) {
    }

    @VisibleForTesting
    void setPreferenceController(StorageItemPreferenceController controller) {
        mPreferenceController = controller;
    }
}
Loading