• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotation.AddedInOrBefore;
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.JSONException;
29 import org.json.JSONObject;
30 
31 import java.io.IOException;
32 import java.util.Objects;
33 
34 /**
35  * uid_io stats about one user ID.
36  *
37  * Contains information about I/O activity that can be attributed to processes running on
38  * behalf of one user of the system, as collected by the kernel.
39  *
40  * @hide
41  *
42  * @deprecated use {@link android.car.watchdog.CarWatchdogManager} and its related classes
43  * for I/O related tasks.
44  */
45 @Deprecated
46 @SystemApi
47 public final class IoStatsEntry implements Parcelable {
48 
49     @AddedInOrBefore(majorVersion = 33)
50     public static final Parcelable.Creator<IoStatsEntry> CREATOR =
51             new Parcelable.Creator<IoStatsEntry>() {
52 
53         public IoStatsEntry createFromParcel(Parcel in) {
54             return new IoStatsEntry(in);
55         }
56 
57         public IoStatsEntry[] newArray(int size) {
58             return new IoStatsEntry[size];
59         }
60     };
61 
62     /**
63      * The user id that this object contains metrics for.
64      *
65      * In many cases this can be converted to a list of Java app packages installed on the device.
66      * In other cases, the user id can refer to either the kernel itself (uid 0), or low-level
67      * system services that are running entirely natively.
68      */
69     @AddedInOrBefore(majorVersion = 33)
70     public final int uid;
71 
72     /**
73      * How long any process running on behalf of this user id running for, in milliseconds.
74      *
75      * This field is allowed to be an approximation and it does not provide any way to
76      * relate uptime to specific processes.
77      */
78     @AddedInOrBefore(majorVersion = 33)
79     public final long runtimeMillis;
80 
81     /**
82      * Statistics for apps running in foreground.
83      */
84     @AddedInOrBefore(majorVersion = 33)
85     public final IoStatsEntry.Metrics foreground;
86 
87     /**
88      * Statistics for apps running in background.
89      */
90     @AddedInOrBefore(majorVersion = 33)
91     public final IoStatsEntry.Metrics background;
92 
IoStatsEntry(int uid, long runtimeMillis, IoStatsEntry.Metrics foreground, IoStatsEntry.Metrics background)93     public IoStatsEntry(int uid,
94             long runtimeMillis, IoStatsEntry.Metrics foreground, IoStatsEntry.Metrics background) {
95         this.uid = uid;
96         this.runtimeMillis = runtimeMillis;
97         this.foreground = Objects.requireNonNull(foreground);
98         this.background = Objects.requireNonNull(background);
99     }
100 
IoStatsEntry(Parcel in)101     public IoStatsEntry(Parcel in) {
102         uid = in.readInt();
103         runtimeMillis = in.readLong();
104         foreground = in.readParcelable(IoStatsEntry.Metrics.class.getClassLoader());
105         background = in.readParcelable(IoStatsEntry.Metrics.class.getClassLoader());
106     }
107 
IoStatsEntry(UidIoRecord record, long runtimeMillis)108     public IoStatsEntry(UidIoRecord record, long runtimeMillis) {
109         uid = record.uid;
110         this.runtimeMillis = runtimeMillis;
111         foreground = new IoStatsEntry.Metrics(record.foreground_rchar,
112                 record.foreground_wchar,
113                 record.foreground_read_bytes,
114                 record.foreground_write_bytes,
115                 record.foreground_fsync);
116         background = new IoStatsEntry.Metrics(record.background_rchar,
117             record.background_wchar,
118             record.background_read_bytes,
119             record.background_write_bytes,
120             record.background_fsync);
121     }
122 
123     @Override
124     @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE)
125     @AddedInOrBefore(majorVersion = 33)
describeContents()126     public int describeContents() {
127         return 0;
128     }
129 
130     @Override
131     @AddedInOrBefore(majorVersion = 33)
writeToParcel(Parcel dest, int flags)132     public void writeToParcel(Parcel dest, int flags) {
133         dest.writeInt(uid);
134         dest.writeLong(runtimeMillis);
135         dest.writeParcelable(foreground, flags);
136         dest.writeParcelable(background, flags);
137     }
138 
139     /**
140      * @hide
141      */
142     @AddedInOrBefore(majorVersion = 33)
writeToJson(JsonWriter jsonWriter)143     public void writeToJson(JsonWriter jsonWriter) throws IOException {
144         jsonWriter.beginObject();
145         jsonWriter.name("uid").value(uid);
146         jsonWriter.name("runtimeMillis").value(runtimeMillis);
147         jsonWriter.name("foreground"); foreground.writeToJson(jsonWriter);
148         jsonWriter.name("background"); background.writeToJson(jsonWriter);
149         jsonWriter.endObject();
150     }
151 
152     /**
153      * @hide
154      */
IoStatsEntry(JSONObject in)155     public IoStatsEntry(JSONObject in) throws JSONException {
156         uid = in.getInt("uid");
157         runtimeMillis = in.getLong("runtimeMillis");
158         foreground = new IoStatsEntry.Metrics(in.getJSONObject("foreground"));
159         background = new IoStatsEntry.Metrics(in.getJSONObject("background"));
160     }
161 
162     /**
163      * Returns the difference between the values stored in this object vs. those
164      * stored in other.
165      *
166      * It is the same as doing a delta() on foreground and background, plus verifying that
167      * both objects refer to the same uid.
168      *
169      * @hide
170      */
171     @AddedInOrBefore(majorVersion = 33)
delta(IoStatsEntry other)172     public IoStatsEntry delta(IoStatsEntry other) {
173         if (uid != other.uid) {
174             throw new IllegalArgumentException("cannot calculate delta between different user IDs");
175         }
176         return new IoStatsEntry(uid,
177                 runtimeMillis - other.runtimeMillis,
178                 foreground.delta(other.foreground), background.delta(other.background));
179     }
180 
181     @Override
equals(Object other)182     public boolean equals(Object other) {
183         if (other instanceof IoStatsEntry) {
184             IoStatsEntry uidIoStatEntry = (IoStatsEntry) other;
185 
186             return uid == uidIoStatEntry.uid
187                     && runtimeMillis == uidIoStatEntry.runtimeMillis
188                     && foreground.equals(uidIoStatEntry.foreground)
189                     && background.equals(uidIoStatEntry.background);
190         }
191         return false;
192     }
193 
194     @Override
hashCode()195     public int hashCode() {
196         return Objects.hash(uid, runtimeMillis, foreground, background);
197     }
198 
199     @Override
toString()200     public String toString() {
201         return String.format("uid = %d, runtime = %d, foreground = %s, background = %s",
202             uid, runtimeMillis, foreground, background);
203     }
204 
205     /**
206      * Validates that this object contains the same I/O metrics as a UidIoStatsRecord.
207      *
208      * It matches UID, and I/O activity values, but ignores runtime.
209      * @hide
210      */
211     @AddedInOrBefore(majorVersion = 33)
representsSameMetrics(UidIoRecord record)212     public boolean representsSameMetrics(UidIoRecord record) {
213         return record.uid == uid
214                 && record.foreground_rchar == foreground.bytesRead
215                 && record.foreground_wchar == foreground.bytesWritten
216                 && record.foreground_read_bytes == foreground.bytesReadFromStorage
217                 && record.foreground_write_bytes == foreground.bytesWrittenToStorage
218                 && record.foreground_fsync == foreground.fsyncCalls
219                 && record.background_rchar == background.bytesRead
220                 && record.background_wchar == background.bytesWritten
221                 && record.background_read_bytes == background.bytesReadFromStorage
222                 && record.background_write_bytes == background.bytesWrittenToStorage
223                 && record.background_fsync == background.fsyncCalls;
224     }
225 
226     /**
227      * I/O activity metrics that pertain to either the foreground or the background state.
228      */
229     public static final class Metrics implements Parcelable {
230 
231         @AddedInOrBefore(majorVersion = 33)
232         public static final Parcelable.Creator<IoStatsEntry.Metrics> CREATOR =
233                 new Parcelable.Creator<IoStatsEntry.Metrics>() {
234             public IoStatsEntry.Metrics createFromParcel(Parcel in) {
235                 return new IoStatsEntry.Metrics(in);
236             }
237 
238             public IoStatsEntry.Metrics[] newArray(int size) {
239                 return new IoStatsEntry.Metrics[size];
240             }
241         };
242 
243         /**
244          * Total bytes that processes running on behalf of this user obtained
245          * via read() system calls.
246          */
247         @AddedInOrBefore(majorVersion = 33)
248         public final long bytesRead;
249 
250         /**
251          * Total bytes that processes running on behalf of this user transferred
252          * via write() system calls.
253          */
254         @AddedInOrBefore(majorVersion = 33)
255         public final long bytesWritten;
256 
257         /**
258          * Total bytes that processes running on behalf of this user obtained
259          * via read() system calls that actually were served by physical storage.
260          */
261         @AddedInOrBefore(majorVersion = 33)
262         public final long bytesReadFromStorage;
263 
264         /**
265          * Total bytes that processes running on behalf of this user transferred
266          * via write() system calls that were actually sent to physical storage.
267          */
268         @AddedInOrBefore(majorVersion = 33)
269         public final long bytesWrittenToStorage;
270 
271         /**
272          * Total number of fsync() system calls that processes running on behalf of this user made.
273          */
274         @AddedInOrBefore(majorVersion = 33)
275         public final long fsyncCalls;
276 
Metrics(long bytesRead, long bytesWritten, long bytesReadFromStorage, long bytesWrittenToStorage, long fsyncCalls)277         public Metrics(long bytesRead, long bytesWritten, long bytesReadFromStorage,
278                 long bytesWrittenToStorage, long fsyncCalls) {
279             this.bytesRead = bytesRead;
280             this.bytesWritten = bytesWritten;
281             this.bytesReadFromStorage = bytesReadFromStorage;
282             this.bytesWrittenToStorage = bytesWrittenToStorage;
283             this.fsyncCalls = fsyncCalls;
284         }
285 
286         @Override
287         @AddedInOrBefore(majorVersion = 33)
describeContents()288         public int describeContents() {
289             return 0;
290         }
291 
292         @Override
293         @AddedInOrBefore(majorVersion = 33)
writeToParcel(Parcel dest, int flags)294         public void writeToParcel(Parcel dest, int flags) {
295             dest.writeLong(bytesRead);
296             dest.writeLong(bytesWritten);
297             dest.writeLong(bytesReadFromStorage);
298             dest.writeLong(bytesWrittenToStorage);
299             dest.writeLong(fsyncCalls);
300         }
301 
302         /**
303          * @hide
304          */
305         @AddedInOrBefore(majorVersion = 33)
writeToJson(JsonWriter jsonWriter)306         public void writeToJson(JsonWriter jsonWriter) throws IOException {
307             jsonWriter.beginObject();
308             jsonWriter.name("bytesRead").value(bytesRead);
309             jsonWriter.name("bytesWritten").value(bytesWritten);
310             jsonWriter.name("bytesReadFromStorage").value(bytesReadFromStorage);
311             jsonWriter.name("bytesWrittenToStorage").value(bytesWrittenToStorage);
312             jsonWriter.name("fsyncCalls").value(fsyncCalls);
313             jsonWriter.endObject();
314         }
315 
Metrics(Parcel in)316         public Metrics(Parcel in) {
317             bytesRead = in.readLong();
318             bytesWritten = in.readLong();
319             bytesReadFromStorage = in.readLong();
320             bytesWrittenToStorage = in.readLong();
321             fsyncCalls = in.readLong();
322         }
323 
324         /**
325          * @hide
326          */
Metrics(JSONObject in)327         public Metrics(JSONObject in) throws JSONException {
328             bytesRead = in.getLong("bytesRead");
329             bytesWritten = in.getLong("bytesWritten");
330             bytesReadFromStorage = in.getLong("bytesReadFromStorage");
331             bytesWrittenToStorage = in.getLong("bytesWrittenToStorage");
332             fsyncCalls = in.getLong("fsyncCalls");
333         }
334 
335         /**
336          * Computes the difference between the values stored in this object
337          * vs. those stored in other
338          *
339          * It is the same as doing
340          * new PerStateMetrics(bytesRead-other.bytesRead,bytesWritten-other.bytesWritten, ...)
341          *
342          * @hide
343          */
344         @AddedInOrBefore(majorVersion = 33)
delta(Metrics other)345         public Metrics delta(Metrics other) {
346             return new Metrics(bytesRead - other.bytesRead,
347                 bytesWritten - other.bytesWritten,
348                 bytesReadFromStorage - other.bytesReadFromStorage,
349                 bytesWrittenToStorage - other.bytesWrittenToStorage,
350                 fsyncCalls - other.fsyncCalls);
351         }
352 
353         @Override
equals(Object other)354         public boolean equals(Object other) {
355             if (other instanceof Metrics) {
356                 Metrics metrics = (Metrics) other;
357 
358                 return (bytesRead == metrics.bytesRead)
359                     && (bytesWritten == metrics.bytesWritten)
360                     && (bytesReadFromStorage == metrics.bytesReadFromStorage)
361                     && (bytesWrittenToStorage == metrics.bytesWrittenToStorage)
362                     && (fsyncCalls == metrics.fsyncCalls);
363             }
364             return false;
365         }
366 
367         @Override
hashCode()368         public int hashCode() {
369             return Objects.hash(bytesRead, bytesWritten, bytesReadFromStorage,
370                 bytesWrittenToStorage, fsyncCalls);
371         }
372 
373         @Override
toString()374         public String toString() {
375             return String.format("bytesRead=%d, bytesWritten=%d, bytesReadFromStorage=%d, "
376                     + "bytesWrittenToStorage=%d, fsyncCalls=%d", bytesRead, bytesWritten,
377                     bytesReadFromStorage, bytesWrittenToStorage, fsyncCalls);
378         }
379     }
380 }
381