• 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
182     @AddedInOrBefore(majorVersion = 33)
equals(Object other)183     public boolean equals(Object other) {
184         if (other instanceof IoStatsEntry) {
185             IoStatsEntry uidIoStatEntry = (IoStatsEntry) other;
186 
187             return uid == uidIoStatEntry.uid
188                     && runtimeMillis == uidIoStatEntry.runtimeMillis
189                     && foreground.equals(uidIoStatEntry.foreground)
190                     && background.equals(uidIoStatEntry.background);
191         }
192         return false;
193     }
194 
195     @Override
196     @AddedInOrBefore(majorVersion = 33)
hashCode()197     public int hashCode() {
198         return Objects.hash(uid, runtimeMillis, foreground, background);
199     }
200 
201     @Override
202     @AddedInOrBefore(majorVersion = 33)
toString()203     public String toString() {
204         return String.format("uid = %d, runtime = %d, foreground = %s, background = %s",
205             uid, runtimeMillis, foreground, background);
206     }
207 
208     /**
209      * Validates that this object contains the same I/O metrics as a UidIoStatsRecord.
210      *
211      * It matches UID, and I/O activity values, but ignores runtime.
212      * @hide
213      */
214     @AddedInOrBefore(majorVersion = 33)
representsSameMetrics(UidIoRecord record)215     public boolean representsSameMetrics(UidIoRecord record) {
216         return record.uid == uid
217                 && record.foreground_rchar == foreground.bytesRead
218                 && record.foreground_wchar == foreground.bytesWritten
219                 && record.foreground_read_bytes == foreground.bytesReadFromStorage
220                 && record.foreground_write_bytes == foreground.bytesWrittenToStorage
221                 && record.foreground_fsync == foreground.fsyncCalls
222                 && record.background_rchar == background.bytesRead
223                 && record.background_wchar == background.bytesWritten
224                 && record.background_read_bytes == background.bytesReadFromStorage
225                 && record.background_write_bytes == background.bytesWrittenToStorage
226                 && record.background_fsync == background.fsyncCalls;
227     }
228 
229     /**
230      * I/O activity metrics that pertain to either the foreground or the background state.
231      */
232     public static final class Metrics implements Parcelable {
233 
234         @AddedInOrBefore(majorVersion = 33)
235         public static final Parcelable.Creator<IoStatsEntry.Metrics> CREATOR =
236                 new Parcelable.Creator<IoStatsEntry.Metrics>() {
237             public IoStatsEntry.Metrics createFromParcel(Parcel in) {
238                 return new IoStatsEntry.Metrics(in);
239             }
240 
241             public IoStatsEntry.Metrics[] newArray(int size) {
242                 return new IoStatsEntry.Metrics[size];
243             }
244         };
245 
246         /**
247          * Total bytes that processes running on behalf of this user obtained
248          * via read() system calls.
249          */
250         @AddedInOrBefore(majorVersion = 33)
251         public final long bytesRead;
252 
253         /**
254          * Total bytes that processes running on behalf of this user transferred
255          * via write() system calls.
256          */
257         @AddedInOrBefore(majorVersion = 33)
258         public final long bytesWritten;
259 
260         /**
261          * Total bytes that processes running on behalf of this user obtained
262          * via read() system calls that actually were served by physical storage.
263          */
264         @AddedInOrBefore(majorVersion = 33)
265         public final long bytesReadFromStorage;
266 
267         /**
268          * Total bytes that processes running on behalf of this user transferred
269          * via write() system calls that were actually sent to physical storage.
270          */
271         @AddedInOrBefore(majorVersion = 33)
272         public final long bytesWrittenToStorage;
273 
274         /**
275          * Total number of fsync() system calls that processes running on behalf of this user made.
276          */
277         @AddedInOrBefore(majorVersion = 33)
278         public final long fsyncCalls;
279 
Metrics(long bytesRead, long bytesWritten, long bytesReadFromStorage, long bytesWrittenToStorage, long fsyncCalls)280         public Metrics(long bytesRead, long bytesWritten, long bytesReadFromStorage,
281                 long bytesWrittenToStorage, long fsyncCalls) {
282             this.bytesRead = bytesRead;
283             this.bytesWritten = bytesWritten;
284             this.bytesReadFromStorage = bytesReadFromStorage;
285             this.bytesWrittenToStorage = bytesWrittenToStorage;
286             this.fsyncCalls = fsyncCalls;
287         }
288 
289         @Override
290         @AddedInOrBefore(majorVersion = 33)
describeContents()291         public int describeContents() {
292             return 0;
293         }
294 
295         @Override
296         @AddedInOrBefore(majorVersion = 33)
writeToParcel(Parcel dest, int flags)297         public void writeToParcel(Parcel dest, int flags) {
298             dest.writeLong(bytesRead);
299             dest.writeLong(bytesWritten);
300             dest.writeLong(bytesReadFromStorage);
301             dest.writeLong(bytesWrittenToStorage);
302             dest.writeLong(fsyncCalls);
303         }
304 
305         /**
306          * @hide
307          */
308         @AddedInOrBefore(majorVersion = 33)
writeToJson(JsonWriter jsonWriter)309         public void writeToJson(JsonWriter jsonWriter) throws IOException {
310             jsonWriter.beginObject();
311             jsonWriter.name("bytesRead").value(bytesRead);
312             jsonWriter.name("bytesWritten").value(bytesWritten);
313             jsonWriter.name("bytesReadFromStorage").value(bytesReadFromStorage);
314             jsonWriter.name("bytesWrittenToStorage").value(bytesWrittenToStorage);
315             jsonWriter.name("fsyncCalls").value(fsyncCalls);
316             jsonWriter.endObject();
317         }
318 
Metrics(Parcel in)319         public Metrics(Parcel in) {
320             bytesRead = in.readLong();
321             bytesWritten = in.readLong();
322             bytesReadFromStorage = in.readLong();
323             bytesWrittenToStorage = in.readLong();
324             fsyncCalls = in.readLong();
325         }
326 
327         /**
328          * @hide
329          */
Metrics(JSONObject in)330         public Metrics(JSONObject in) throws JSONException {
331             bytesRead = in.getLong("bytesRead");
332             bytesWritten = in.getLong("bytesWritten");
333             bytesReadFromStorage = in.getLong("bytesReadFromStorage");
334             bytesWrittenToStorage = in.getLong("bytesWrittenToStorage");
335             fsyncCalls = in.getLong("fsyncCalls");
336         }
337 
338         /**
339          * Computes the difference between the values stored in this object
340          * vs. those stored in other
341          *
342          * It is the same as doing
343          * new PerStateMetrics(bytesRead-other.bytesRead,bytesWritten-other.bytesWritten, ...)
344          *
345          * @hide
346          */
347         @AddedInOrBefore(majorVersion = 33)
delta(Metrics other)348         public Metrics delta(Metrics other) {
349             return new Metrics(bytesRead - other.bytesRead,
350                 bytesWritten - other.bytesWritten,
351                 bytesReadFromStorage - other.bytesReadFromStorage,
352                 bytesWrittenToStorage - other.bytesWrittenToStorage,
353                 fsyncCalls - other.fsyncCalls);
354         }
355 
356         @Override
357         @AddedInOrBefore(majorVersion = 33)
equals(Object other)358         public boolean equals(Object other) {
359             if (other instanceof Metrics) {
360                 Metrics metrics = (Metrics) other;
361 
362                 return (bytesRead == metrics.bytesRead)
363                     && (bytesWritten == metrics.bytesWritten)
364                     && (bytesReadFromStorage == metrics.bytesReadFromStorage)
365                     && (bytesWrittenToStorage == metrics.bytesWrittenToStorage)
366                     && (fsyncCalls == metrics.fsyncCalls);
367             }
368             return false;
369         }
370 
371         @Override
372         @AddedInOrBefore(majorVersion = 33)
hashCode()373         public int hashCode() {
374             return Objects.hash(bytesRead, bytesWritten, bytesReadFromStorage,
375                 bytesWrittenToStorage, fsyncCalls);
376         }
377 
378         @Override
379         @AddedInOrBefore(majorVersion = 33)
toString()380         public String toString() {
381             return String.format("bytesRead=%d, bytesWritten=%d, bytesReadFromStorage=%d, "
382                     + "bytesWrittenToStorage=%d, fsyncCalls=%d", bytesRead, bytesWritten,
383                     bytesReadFromStorage, bytesWrittenToStorage, fsyncCalls);
384         }
385     }
386 }
387