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 import android.text.format.Formatter; 21 22 import androidx.annotation.Nullable; 23 import androidx.annotation.StringRes; 24 import androidx.preference.Preference; 25 26 import com.android.internal.util.Preconditions; 27 import com.android.settingslib.applications.StorageStatsSource; 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 long codeSize = mLastResult.getCodeBytes(); 74 long dataSize = 75 mDataCleared ? 0 : mLastResult.getDataBytes() - mLastResult.getCacheBytes(); 76 if (mLastCodeSize != codeSize) { 77 mLastCodeSize = codeSize; 78 mAppSize.setSummary(getSizeStr(context, codeSize)); 79 } 80 if (mLastDataSize != dataSize) { 81 mLastDataSize = dataSize; 82 mDataSize.setSummary(getSizeStr(context, dataSize)); 83 } 84 long cacheSize = (mDataCleared || mCachedCleared) ? 0 : mLastResult.getCacheBytes(); 85 if (mLastCacheSize != cacheSize) { 86 mLastCacheSize = cacheSize; 87 mCacheSize.setSummary(getSizeStr(context, cacheSize)); 88 } 89 90 long totalSize = codeSize + dataSize + cacheSize; 91 if (mLastTotalSize != totalSize) { 92 mLastTotalSize = totalSize; 93 mTotalSize.setSummary(getSizeStr(context, totalSize)); 94 } 95 } 96 } 97 98 /** 99 * Sets a result for the controller to use to update the UI. 100 * @param result A result for the UI. If null, count as a failed calculation. 101 */ setResult(StorageStatsSource.AppStorageStats result)102 public void setResult(StorageStatsSource.AppStorageStats result) { 103 mLastResult = result; 104 mLastResultFailed = result == null; 105 } 106 107 /** 108 * Sets if we have cleared the cache and should zero the cache bytes. 109 * When the cache is cleared, the cache directories are recreated. These directories have 110 * some size, but are empty. We zero this out to best match user expectations. 111 */ setCacheCleared(boolean isCleared)112 public void setCacheCleared(boolean isCleared) { 113 mCachedCleared = isCleared; 114 } 115 116 /** 117 * Sets if we have cleared data and should zero the data bytes. 118 * When the data is cleared, the directory are recreated. Directories have some size, but are 119 * empty. We zero this out to best match user expectations. 120 */ setDataCleared(boolean isCleared)121 public void setDataCleared(boolean isCleared) { 122 mDataCleared = isCleared; 123 } 124 125 /** 126 * Returns the last result calculated, if it exists. If it does not, returns null. 127 */ getLastResult()128 public StorageStatsSource.AppStorageStats getLastResult() { 129 return mLastResult; 130 } 131 getSizeStr(Context context, long size)132 private String getSizeStr(Context context, long size) { 133 return Formatter.formatFileSize(context, size); 134 } 135 136 public static class Builder { 137 private Preference mTotalSize; 138 private Preference mAppSize; 139 private Preference mDataSize; 140 private Preference mCacheSize; 141 private @StringRes int mComputing; 142 private @StringRes int mError; 143 setAppSizePreference(Preference preference)144 public Builder setAppSizePreference(Preference preference) { 145 mAppSize = preference; 146 return this; 147 } 148 setDataSizePreference(Preference preference)149 public Builder setDataSizePreference(Preference preference) { 150 mDataSize = preference; 151 return this; 152 } 153 setCacheSizePreference(Preference preference)154 public Builder setCacheSizePreference(Preference preference) { 155 mCacheSize = preference; 156 return this; 157 } 158 setTotalSizePreference(Preference preference)159 public Builder setTotalSizePreference(Preference preference) { 160 mTotalSize = preference; 161 return this; 162 } 163 setComputingString(@tringRes int sequence)164 public Builder setComputingString(@StringRes int sequence) { 165 mComputing = sequence; 166 return this; 167 } 168 setErrorString(@tringRes int sequence)169 public Builder setErrorString(@StringRes int sequence) { 170 mError = sequence; 171 return this; 172 } 173 build()174 public AppStorageSizesController build() { 175 return new AppStorageSizesController( 176 Preconditions.checkNotNull(mTotalSize), 177 Preconditions.checkNotNull(mAppSize), 178 Preconditions.checkNotNull(mDataSize), 179 Preconditions.checkNotNull(mCacheSize), 180 mComputing, 181 mError); 182 } 183 } 184 } 185