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.applications; 18 19 import android.content.Context; 20 21 import androidx.annotation.Nullable; 22 import androidx.annotation.StringRes; 23 import androidx.preference.Preference; 24 25 import com.android.internal.util.Preconditions; 26 import com.android.settingslib.applications.StorageStatsSource; 27 import com.android.settingslib.spaprivileged.model.app.AppStorageRepositoryImpl; 28 29 /** 30 * Handles setting the sizes for the app info screen. 31 */ 32 public class AppStorageSizesController { 33 private final Preference mTotalSize; 34 private final Preference mAppSize; 35 private final Preference mDataSize; 36 private final Preference mCacheSize; 37 private final @StringRes int mComputing; 38 private final @StringRes int mError; 39 40 @Nullable 41 private StorageStatsSource.AppStorageStats mLastResult; 42 private boolean mLastResultFailed; 43 private boolean mCachedCleared; 44 private boolean mDataCleared; 45 private long mLastCodeSize = -1; 46 private long mLastDataSize = -1; 47 private long mLastCacheSize = -1; 48 private long mLastTotalSize = -1; 49 AppStorageSizesController(Preference total, Preference app, Preference data, Preference cache, @StringRes int computing, @StringRes int error)50 private AppStorageSizesController(Preference total, Preference app, 51 Preference data, Preference cache, @StringRes int computing, @StringRes int error) { 52 mTotalSize = total; 53 mAppSize = app; 54 mDataSize = data; 55 mCacheSize = cache; 56 mComputing = computing; 57 mError = error; 58 } 59 60 /** 61 * Updates the UI using storage stats. 62 * @param context Context to use to fetch strings 63 */ updateUi(Context context)64 public void updateUi(Context context) { 65 if (mLastResult == null) { 66 int errorRes = mLastResultFailed ? mError : mComputing; 67 68 mAppSize.setSummary(errorRes); 69 mDataSize.setSummary(errorRes); 70 mCacheSize.setSummary(errorRes); 71 mTotalSize.setSummary(errorRes); 72 } else { 73 var appStorageRepository = new AppStorageRepositoryImpl(context); 74 long codeSize = mLastResult.getCodeBytes(); 75 long dataSize = 76 mDataCleared ? 0 : mLastResult.getDataBytes() - mLastResult.getCacheBytes(); 77 if (mLastCodeSize != codeSize) { 78 mLastCodeSize = codeSize; 79 mAppSize.setSummary(appStorageRepository.formatSizeBytes(codeSize)); 80 } 81 if (mLastDataSize != dataSize) { 82 mLastDataSize = dataSize; 83 mDataSize.setSummary(appStorageRepository.formatSizeBytes(dataSize)); 84 } 85 long cacheSize = (mDataCleared || mCachedCleared) ? 0 : mLastResult.getCacheBytes(); 86 if (mLastCacheSize != cacheSize) { 87 mLastCacheSize = cacheSize; 88 mCacheSize.setSummary(appStorageRepository.formatSizeBytes(cacheSize)); 89 } 90 91 long totalSize = codeSize + dataSize + cacheSize; 92 if (mLastTotalSize != totalSize) { 93 mLastTotalSize = totalSize; 94 mTotalSize.setSummary(appStorageRepository.formatSizeBytes(totalSize)); 95 } 96 } 97 } 98 99 /** 100 * Sets a result for the controller to use to update the UI. 101 * @param result A result for the UI. If null, count as a failed calculation. 102 */ setResult(StorageStatsSource.AppStorageStats result)103 public void setResult(StorageStatsSource.AppStorageStats result) { 104 mLastResult = result; 105 mLastResultFailed = result == null; 106 } 107 108 /** 109 * Sets if we have cleared the cache and should zero the cache bytes. 110 * When the cache is cleared, the cache directories are recreated. These directories have 111 * some size, but are empty. We zero this out to best match user expectations. 112 */ setCacheCleared(boolean isCleared)113 public void setCacheCleared(boolean isCleared) { 114 mCachedCleared = isCleared; 115 } 116 117 /** 118 * Sets if we have cleared data and should zero the data bytes. 119 * When the data is cleared, the directory are recreated. Directories have some size, but are 120 * empty. We zero this out to best match user expectations. 121 */ setDataCleared(boolean isCleared)122 public void setDataCleared(boolean isCleared) { 123 mDataCleared = isCleared; 124 } 125 126 /** 127 * Returns the last result calculated, if it exists. If it does not, returns null. 128 */ getLastResult()129 public StorageStatsSource.AppStorageStats getLastResult() { 130 return mLastResult; 131 } 132 133 public static class Builder { 134 private Preference mTotalSize; 135 private Preference mAppSize; 136 private Preference mDataSize; 137 private Preference mCacheSize; 138 private @StringRes int mComputing; 139 private @StringRes int mError; 140 setAppSizePreference(Preference preference)141 public Builder setAppSizePreference(Preference preference) { 142 mAppSize = preference; 143 return this; 144 } 145 setDataSizePreference(Preference preference)146 public Builder setDataSizePreference(Preference preference) { 147 mDataSize = preference; 148 return this; 149 } 150 setCacheSizePreference(Preference preference)151 public Builder setCacheSizePreference(Preference preference) { 152 mCacheSize = preference; 153 return this; 154 } 155 setTotalSizePreference(Preference preference)156 public Builder setTotalSizePreference(Preference preference) { 157 mTotalSize = preference; 158 return this; 159 } 160 setComputingString(@tringRes int sequence)161 public Builder setComputingString(@StringRes int sequence) { 162 mComputing = sequence; 163 return this; 164 } 165 setErrorString(@tringRes int sequence)166 public Builder setErrorString(@StringRes int sequence) { 167 mError = sequence; 168 return this; 169 } 170 build()171 public AppStorageSizesController build() { 172 return new AppStorageSizesController( 173 Preconditions.checkNotNull(mTotalSize), 174 Preconditions.checkNotNull(mAppSize), 175 Preconditions.checkNotNull(mDataSize), 176 Preconditions.checkNotNull(mCacheSize), 177 mComputing, 178 mError); 179 } 180 } 181 } 182