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 Drawable mUserIcon; 57 private long mSize; 58 private long mTotalSizeBytes; 59 60 /** 61 * Adds the appropriate controllers to a controller list for handling all secondary users on 62 * a device. 63 * 64 * @param context Context for initializing the preference controllers. 65 * @param userManager UserManagerWrapper for figuring out which controllers to add. 66 */ getSecondaryUserControllers( Context context, UserManager userManager)67 public static List<AbstractPreferenceController> getSecondaryUserControllers( 68 Context context, UserManager userManager) { 69 List<AbstractPreferenceController> controllers = new ArrayList<>(); 70 UserInfo primaryUser = userManager.getPrimaryUser(); 71 boolean addedUser = false; 72 List<UserInfo> infos = userManager.getUsers(); 73 for (int i = 0, size = infos.size(); i < size; i++) { 74 UserInfo info = infos.get(i); 75 if (info.isPrimary()) { 76 continue; 77 } 78 79 if (info == null || Utils.isProfileOf(primaryUser, info)) { 80 controllers.add( 81 new UserProfileController(context, info, USER_PROFILE_INSERTION_LOCATION)); 82 continue; 83 } 84 85 controllers.add(new SecondaryUserController(context, info)); 86 addedUser = true; 87 } 88 89 if (!addedUser) { 90 controllers.add(new NoSecondaryUserController(context)); 91 } 92 return controllers; 93 } 94 95 /** 96 * Constructor for a given secondary user. 97 * 98 * @param context Context to initialize the underlying {@link AbstractPreferenceController}. 99 * @param info {@link UserInfo} for the secondary user which this controllers covers. 100 */ 101 @VisibleForTesting SecondaryUserController(Context context, @NonNull UserInfo info)102 SecondaryUserController(Context context, @NonNull UserInfo info) { 103 super(context); 104 mUser = info; 105 mSize = SIZE_NOT_SET; 106 } 107 108 @Override displayPreference(PreferenceScreen screen)109 public void displayPreference(PreferenceScreen screen) { 110 if (mStoragePreference == null) { 111 mStoragePreference = new StorageItemPreference(screen.getContext()); 112 113 PreferenceGroup group = 114 screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); 115 mStoragePreference.setTitle(mUser.name); 116 mStoragePreference.setKey(PREFERENCE_KEY_BASE + mUser.id); 117 if (mSize != SIZE_NOT_SET) { 118 mStoragePreference.setStorageSize(mSize, mTotalSizeBytes); 119 } 120 121 group.setVisible(true); 122 group.addPreference(mStoragePreference); 123 maybeSetIcon(); 124 } 125 } 126 127 @Override isAvailable()128 public boolean isAvailable() { 129 return true; 130 } 131 132 @Override getPreferenceKey()133 public String getPreferenceKey() { 134 return mStoragePreference != null ? mStoragePreference.getKey() : null; 135 } 136 137 /** 138 * Returns the user for which this is the secondary user controller. 139 */ 140 @NonNull getUser()141 public UserInfo getUser() { 142 return mUser; 143 } 144 145 /** 146 * Sets the size for the preference. 147 * 148 * @param size Size in bytes. 149 */ setSize(long size)150 public void setSize(long size) { 151 mSize = size; 152 if (mStoragePreference != null) { 153 mStoragePreference.setStorageSize(mSize, mTotalSizeBytes); 154 } 155 } 156 157 /** 158 * Sets the total size for the preference for the progress bar. 159 * 160 * @param totalSizeBytes Total size in bytes. 161 */ setTotalSize(long totalSizeBytes)162 public void setTotalSize(long totalSizeBytes) { 163 mTotalSizeBytes = totalSizeBytes; 164 } 165 handleResult(SparseArray<StorageAsyncLoader.AppsStorageResult> stats)166 public void handleResult(SparseArray<StorageAsyncLoader.AppsStorageResult> stats) { 167 int userId = getUser().id; 168 StorageAsyncLoader.AppsStorageResult result = stats.get(userId); 169 if (result != null) { 170 setSize(result.externalStats.totalBytes); 171 } 172 } 173 174 @Override handleUserIcons(SparseArray<Drawable> fetchedIcons)175 public void handleUserIcons(SparseArray<Drawable> fetchedIcons) { 176 mUserIcon = fetchedIcons.get(mUser.id); 177 maybeSetIcon(); 178 } 179 maybeSetIcon()180 private void maybeSetIcon() { 181 if (mUserIcon != null && mStoragePreference != null) { 182 mStoragePreference.setIcon(mUserIcon); 183 } 184 } 185 186 private static class NoSecondaryUserController extends AbstractPreferenceController implements 187 PreferenceControllerMixin { NoSecondaryUserController(Context context)188 public NoSecondaryUserController(Context context) { 189 super(context); 190 } 191 192 @Override displayPreference(PreferenceScreen screen)193 public void displayPreference(PreferenceScreen screen) { 194 final PreferenceGroup group = screen.findPreference(TARGET_PREFERENCE_GROUP_KEY); 195 if (group == null) { 196 return; 197 } 198 screen.removePreference(group); 199 } 200 201 @Override isAvailable()202 public boolean isAvailable() { 203 return true; 204 } 205 206 @Override getPreferenceKey()207 public String getPreferenceKey() { 208 return null; 209 } 210 211 } 212 } 213