1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.deviceinfo.storage; 18 19 import android.content.Context; 20 import android.content.pm.UserInfo; 21 import android.graphics.drawable.Drawable; 22 import android.os.UserManager; 23 import android.util.SparseArray; 24 25 import androidx.annotation.NonNull; 26 import androidx.annotation.Nullable; 27 import androidx.annotation.VisibleForTesting; 28 import androidx.preference.PreferenceGroup; 29 import androidx.preference.PreferenceScreen; 30 31 import com.android.settings.Utils; 32 import com.android.settings.core.PreferenceControllerMixin; 33 import com.android.settings.deviceinfo.StorageItemPreference; 34 import com.android.settingslib.core.AbstractPreferenceController; 35 36 import java.util.ArrayList; 37 import java.util.List; 38 39 /** 40 * SecondaryUserController controls the preferences on the Storage screen which had to do with 41 * secondary users. 42 */ 43 public class SecondaryUserController extends AbstractPreferenceController implements 44 PreferenceControllerMixin, StorageAsyncLoader.ResultHandler, 45 UserIconLoader.UserIconHandler { 46 // PreferenceGroupKey to try to add our preference onto. 47 private static final String TARGET_PREFERENCE_GROUP_KEY = "pref_secondary_users"; 48 private static final String PREFERENCE_KEY_BASE = "pref_user_"; 49 private static final int USER_PROFILE_INSERTION_LOCATION = 6; 50 private static final int SIZE_NOT_SET = -1; 51 52 private @NonNull 53 UserInfo mUser; 54 private @Nullable 55 StorageItemPreference mStoragePreference; 56 private PreferenceGroup mPreferenceGroup; 57 private Drawable mUserIcon; 58 private long mSize; 59 private long mTotalSizeBytes; 60 private boolean mIsVisible; 61 62 /** 63 * Adds the appropriate controllers to a controller list for handling all secondary users on 64 * a device. 65 * 66 * @param context Context for initializing the preference controllers. 67 * @param userManager UserManagerWrapper for figuring out which controllers to add. 68 * @param isWorkProfileOnly only shows secondary users of work profile. 69 * (e.g., it should be true in work profile tab) 70 */ getSecondaryUserControllers( Context context, UserManager userManager, boolean isWorkProfileOnly)71 public static List<AbstractPreferenceController> getSecondaryUserControllers( 72 Context context, UserManager userManager, boolean isWorkProfileOnly) { 73 74 List<AbstractPreferenceController> controllers = new ArrayList<>(); 75 UserInfo primaryUser = userManager.getPrimaryUser(); 76 boolean addedUser = false; 77 List<UserInfo> infos = userManager.getUsers(); 78 for (int i = 0, size = infos.size(); i < size; i++) { 79 UserInfo info = infos.get(i); 80 if (info.isPrimary()) { 81 continue; 82 } 83 84 if (Utils.isProfileOf(primaryUser, info)) { 85 continue; 86 } 87 88 if (isWorkProfileOnly && !info.isManagedProfile()) { 89 continue; 90 } 91 92 controllers.add(new SecondaryUserController(context, info)); 93 addedUser = true; 94 } 95 96 if (!addedUser) { 97 controllers.add(new NoSecondaryUserController(context)); 98 } 99 return controllers; 100 } 101 102 /** 103 * Constructor for a given secondary user. 104 * 105 * @param context Context to initialize the underlying {@link AbstractPreferenceController}. 106 * @param info {@link UserInfo} for the secondary user which this controllers covers. 107 */ 108 @VisibleForTesting SecondaryUserController(Context context, @NonNull UserInfo info)109 SecondaryUserController(Context context, @NonNull UserInfo info) { 110 super(context); 111 mUser = info; 112 mSize = SIZE_NOT_SET; 113 } 114 115 @Override displayPreference(PreferenceScreen screen)116 public void displayPreference(PreferenceScreen screen) { 117 if (mStoragePreference == null) { 118 mStoragePreference = new StorageItemPreference(screen.getContext()); 119 120 mPreferenceGroup = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); 121 mStoragePreference.setTitle(mUser.name); 122 mStoragePreference.setKey(PREFERENCE_KEY_BASE + mUser.id); 123 if (mSize != SIZE_NOT_SET) { 124 mStoragePreference.setStorageSize(mSize, mTotalSizeBytes); 125 } 126 127 mPreferenceGroup.setVisible(mIsVisible); 128 mPreferenceGroup.addPreference(mStoragePreference); 129 maybeSetIcon(); 130 } 131 } 132 133 @Override isAvailable()134 public boolean isAvailable() { 135 return true; 136 } 137 138 @Override getPreferenceKey()139 public String getPreferenceKey() { 140 return mStoragePreference != null ? mStoragePreference.getKey() : null; 141 } 142 143 /** 144 * Returns the user for which this is the secondary user controller. 145 */ 146 @NonNull getUser()147 public UserInfo getUser() { 148 return mUser; 149 } 150 151 /** 152 * Sets the size for the preference. 153 * 154 * @param size Size in bytes. 155 */ setSize(long size)156 public void setSize(long size) { 157 mSize = size; 158 if (mStoragePreference != null) { 159 mStoragePreference.setStorageSize(mSize, mTotalSizeBytes); 160 } 161 } 162 163 /** 164 * Sets the total size for the preference for the progress bar. 165 * 166 * @param totalSizeBytes Total size in bytes. 167 */ setTotalSize(long totalSizeBytes)168 public void setTotalSize(long totalSizeBytes) { 169 mTotalSizeBytes = totalSizeBytes; 170 } 171 172 /** 173 * Sets visibility of the PreferenceGroup of secondary user. 174 * 175 * @param visible Visibility of the PreferenceGroup. 176 */ setPreferenceGroupVisible(boolean visible)177 public void setPreferenceGroupVisible(boolean visible) { 178 mIsVisible = visible; 179 if (mPreferenceGroup != null) { 180 mPreferenceGroup.setVisible(mIsVisible); 181 } 182 } 183 184 @Override handleResult(SparseArray<StorageAsyncLoader.StorageResult> stats)185 public void handleResult(SparseArray<StorageAsyncLoader.StorageResult> stats) { 186 final StorageAsyncLoader.StorageResult result = stats.get(getUser().id); 187 if (result != null) { 188 setSize(result.externalStats.totalBytes); 189 } 190 } 191 192 @Override handleUserIcons(SparseArray<Drawable> fetchedIcons)193 public void handleUserIcons(SparseArray<Drawable> fetchedIcons) { 194 mUserIcon = fetchedIcons.get(mUser.id); 195 maybeSetIcon(); 196 } 197 maybeSetIcon()198 private void maybeSetIcon() { 199 if (mUserIcon != null && mStoragePreference != null) { 200 mStoragePreference.setIcon(mUserIcon); 201 } 202 } 203 204 @VisibleForTesting 205 static class NoSecondaryUserController extends AbstractPreferenceController implements 206 PreferenceControllerMixin { NoSecondaryUserController(Context context)207 public NoSecondaryUserController(Context context) { 208 super(context); 209 } 210 211 @Override displayPreference(PreferenceScreen screen)212 public void displayPreference(PreferenceScreen screen) { 213 final PreferenceGroup group = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); 214 if (group == null) { 215 return; 216 } 217 screen.removePreference(group); 218 } 219 220 @Override isAvailable()221 public boolean isAvailable() { 222 return true; 223 } 224 225 @Override getPreferenceKey()226 public String getPreferenceKey() { 227 return null; 228 } 229 } 230 } 231