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 package android.car.storagemonitoring; 17 18 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE; 19 20 import android.annotation.SystemApi; 21 import android.car.storagemonitoring.IoStatsEntry.Metrics; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.util.JsonWriter; 25 26 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 27 28 import org.json.JSONArray; 29 import org.json.JSONException; 30 import org.json.JSONObject; 31 32 import java.io.IOException; 33 import java.util.ArrayList; 34 import java.util.List; 35 import java.util.Objects; 36 import java.util.StringJoiner; 37 38 /** 39 * Delta of uid_io stats taken at a sample point. 40 * 41 * @hide 42 * 43 * @deprecated use {@link android.car.watchdog.CarWatchdogManager} and its related classes 44 * for I/O related tasks. 45 */ 46 @Deprecated 47 @SystemApi 48 public final class IoStats implements Parcelable { 49 public static final Creator<IoStats> CREATOR = new Creator<IoStats>() { 50 @Override 51 public IoStats createFromParcel(Parcel in) { 52 return new IoStats(in); 53 } 54 55 @Override 56 public IoStats[] newArray(int size) { 57 return new IoStats[size]; 58 } 59 }; 60 61 private final List<IoStatsEntry> mStats; 62 private final long mUptimeTimestamp; 63 IoStats(List<IoStatsEntry> stats, long timestamp)64 public IoStats(List<IoStatsEntry> stats, long timestamp) { 65 mStats = stats; 66 mUptimeTimestamp = timestamp; 67 } 68 IoStats(Parcel in)69 public IoStats(Parcel in) { 70 mStats = in.createTypedArrayList(IoStatsEntry.CREATOR); 71 mUptimeTimestamp = in.readLong(); 72 } 73 74 /** 75 * @hide 76 */ IoStats(JSONObject in)77 public IoStats(JSONObject in) throws JSONException { 78 mUptimeTimestamp = in.getInt("uptime"); 79 JSONArray statsArray = in.getJSONArray("stats"); 80 mStats = new ArrayList<>(); 81 for (int i = 0; i < statsArray.length(); ++i) { 82 mStats.add(new IoStatsEntry(statsArray.getJSONObject(i))); 83 } 84 } 85 86 @Override writeToParcel(Parcel dest, int flags)87 public void writeToParcel(Parcel dest, int flags) { 88 dest.writeTypedList(mStats); 89 dest.writeLong(mUptimeTimestamp); 90 } 91 92 /** 93 * @hide 94 */ writeToJson(JsonWriter jsonWriter)95 public void writeToJson(JsonWriter jsonWriter) throws IOException { 96 jsonWriter.beginObject(); 97 jsonWriter.name("uptime").value(mUptimeTimestamp); 98 jsonWriter.name("stats").beginArray(); 99 for (IoStatsEntry stat : mStats) { 100 stat.writeToJson(jsonWriter); 101 } 102 jsonWriter.endArray(); 103 jsonWriter.endObject(); 104 } 105 106 @Override 107 @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE) describeContents()108 public int describeContents() { 109 return 0; 110 } 111 getTimestamp()112 public long getTimestamp() { 113 return mUptimeTimestamp; 114 } 115 getStats()116 public List<IoStatsEntry> getStats() { 117 return mStats; 118 } 119 120 @Override hashCode()121 public int hashCode() { 122 return Objects.hash(mStats, mUptimeTimestamp); 123 } 124 125 /** 126 * Returns user's stats ({@link IoStatsEntry}). 127 * 128 * @param uid Android's user id 129 */ getUserIdStats(int uid)130 public IoStatsEntry getUserIdStats(int uid) { 131 for (IoStatsEntry stats : getStats()) { 132 if (stats.uid == uid) { 133 return stats; 134 } 135 } 136 137 return null; 138 } 139 140 /** 141 * Returns the following foreground total metrics: bytes written and read, bytes read from and 142 * written to storage, and number of sync calls. 143 */ getForegroundTotals()144 public IoStatsEntry.Metrics getForegroundTotals() { 145 long bytesRead = 0; 146 long bytesWritten = 0; 147 long bytesReadFromStorage = 0; 148 long bytesWrittenToStorage = 0; 149 long fsyncCalls = 0; 150 151 for (IoStatsEntry stats : getStats()) { 152 bytesRead += stats.foreground.bytesRead; 153 bytesWritten += stats.foreground.bytesWritten; 154 bytesReadFromStorage += stats.foreground.bytesReadFromStorage; 155 bytesWrittenToStorage += stats.foreground.bytesWrittenToStorage; 156 fsyncCalls += stats.foreground.fsyncCalls; 157 } 158 159 return new Metrics(bytesRead, 160 bytesWritten, 161 bytesReadFromStorage, 162 bytesWrittenToStorage, 163 fsyncCalls); 164 } 165 166 /** 167 * Returns the following background total metrics: bytes written and read, bytes read from and 168 * written to storage, and number of sync calls. 169 */ getBackgroundTotals()170 public IoStatsEntry.Metrics getBackgroundTotals() { 171 long bytesRead = 0; 172 long bytesWritten = 0; 173 long bytesReadFromStorage = 0; 174 long bytesWrittenToStorage = 0; 175 long fsyncCalls = 0; 176 177 for (IoStatsEntry stats : getStats()) { 178 bytesRead += stats.background.bytesRead; 179 bytesWritten += stats.background.bytesWritten; 180 bytesReadFromStorage += stats.background.bytesReadFromStorage; 181 bytesWrittenToStorage += stats.background.bytesWrittenToStorage; 182 fsyncCalls += stats.background.fsyncCalls; 183 } 184 185 return new Metrics(bytesRead, 186 bytesWritten, 187 bytesReadFromStorage, 188 bytesWrittenToStorage, 189 fsyncCalls); 190 } 191 192 /** 193 * Returns the sum of all foreground and background metrics (bytes written, bytes read from 194 * storage, bytes written to storage and number of sync calls). 195 */ getTotals()196 public IoStatsEntry.Metrics getTotals() { 197 IoStatsEntry.Metrics foreground = getForegroundTotals(); 198 IoStatsEntry.Metrics background = getBackgroundTotals(); 199 200 return new IoStatsEntry.Metrics(foreground.bytesRead + background.bytesRead, 201 foreground.bytesWritten + background.bytesWritten, 202 foreground.bytesReadFromStorage + background.bytesReadFromStorage, 203 foreground.bytesWrittenToStorage + background.bytesWrittenToStorage, 204 foreground.fsyncCalls + background.fsyncCalls); 205 } 206 207 @Override equals(Object other)208 public boolean equals(Object other) { 209 if (other instanceof IoStats) { 210 IoStats delta = (IoStats) other; 211 return delta.getTimestamp() == getTimestamp() 212 && delta.getStats().equals(getStats()); 213 } 214 return false; 215 } 216 217 @Override toString()218 public String toString() { 219 StringJoiner stringJoiner = new StringJoiner(", "); 220 for (IoStatsEntry stats : getStats()) { 221 stringJoiner.add(stats.toString()); 222 } 223 return "timestamp = " + getTimestamp() + ", stats = " + stringJoiner.toString(); 224 } 225 } 226