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 android.app.usage;
18 
19 import android.annotation.BytesLong;
20 import android.annotation.FlaggedApi;
21 import android.annotation.IntDef;
22 import android.content.Context;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.os.UserHandle;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 
30 /**
31  * Storage statistics for a UID, package, or {@link UserHandle} on a single
32  * storage volume.
33  *
34  * @see StorageStatsManager
35  */
36 public final class StorageStats implements Parcelable {
37     /** @hide */ public long codeBytes;
38     /** @hide */ public long dataBytes;
39     /** @hide */ public long cacheBytes;
40     /** @hide */ public long apkBytes;
41     /** @hide */ public long libBytes;
42     /** @hide */ public long dmBytes;
43     /** @hide */ public long dexoptBytes;
44     /** @hide */ public long curProfBytes;
45     /** @hide */ public long refProfBytes;
46     /** @hide */ public long externalCacheBytes;
47 
48     /**
49      * Represents all nonstale dexopt and runtime artifacts of application.
50      * This includes AOT-compiled code and other data that can speed up app execution.
51      * For more detailed information, read the
52      * <a href="https://source.android.com/docs/core/runtime/jit-compiler#flow">JIT compiler</a>
53      * guide.
54      *
55      * Dexopt artifacts become stale when one of their dependencies
56      * has changed. They may be cleaned up or replaced by ART Services at any time.
57      *
58      * For a preload app, this type includes dexopt artifacts on readonly partitions
59      * if they are up-to-date.
60      *
61      * Can be used as an input to {@link #getAppBytesByDataType(int)}
62      * to get the sum of sizes for files of this type. The sum might include the size of data
63      * that is part of appBytes, dataBytes or cacheBytes.
64      */
65     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
66     public static final int APP_DATA_TYPE_FILE_TYPE_DEXOPT_ARTIFACT = 0;
67 
68     /**
69      * Represents reference profile of application.
70      *
71      * Reference profiles are the ones used during the last profile-guided dexopt.
72      * If the last dexopt wasn't profile-guided, then these profiles were not used.
73      *
74      * Can be used as an input to {@link #getAppBytesByDataType(int)}
75      * to get the size of files of this type.
76      */
77     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
78     public static final int APP_DATA_TYPE_FILE_TYPE_REFERENCE_PROFILE = 1;
79 
80     /**
81      * Represents current profile of application.
82      *
83      * Current profiles may or may not be used during the next profile-guided dexopt.
84      *
85      * Can be used as an input to {@link #getAppBytesByDataType(int)}
86      * to get the size of files of this type. This size fluctuates regularly,
87      * it goes up when the user uses more and more classes/methods and comes down when
88      * a deamon merges this into the ref profile and does profile-guided dexopt.
89      */
90     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
91     public static final int APP_DATA_TYPE_FILE_TYPE_CURRENT_PROFILE = 2;
92 
93     /**
94      * Represents all .apk files in application code path.
95      * Can be used as an input to {@link #getAppBytesByDataType(int)}
96      * to get the sum of sizes for files of this type.
97      */
98     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
99     public static final int APP_DATA_TYPE_FILE_TYPE_APK = 3;
100 
101     /**
102      * Represents all .dm files in application code path.
103      * Can be used as an input to {@link #getAppBytesByDataType(int)}
104      * to get the sum of sizes for files of this type.
105      */
106     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
107     public static final int APP_DATA_TYPE_FILE_TYPE_DM = 4;
108 
109     /**
110      * Represents lib/ in application code path.
111      * Can be used as an input to {@link #getAppBytesByDataType(int)}
112      * to get the size of lib/ directory.
113      */
114     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
115     public static final int APP_DATA_TYPE_LIB = 5;
116 
117     /**
118      * Keep in sync with the file types defined above.
119      * @hide
120      */
121     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
122     @IntDef(flag = false, value = {
123         APP_DATA_TYPE_FILE_TYPE_DEXOPT_ARTIFACT,
124         APP_DATA_TYPE_FILE_TYPE_REFERENCE_PROFILE,
125         APP_DATA_TYPE_FILE_TYPE_CURRENT_PROFILE,
126         APP_DATA_TYPE_FILE_TYPE_APK,
127         APP_DATA_TYPE_FILE_TYPE_DM,
128         APP_DATA_TYPE_LIB,
129     })
130     @Retention(RetentionPolicy.SOURCE)
131     public @interface AppDataType {}
132 
133     /**
134      * Return the size of app. This includes {@code APK} files, optimized
135      * compiler output, and unpacked native libraries.
136      * <p>
137      * If the primary external/shared storage is hosted on this storage device,
138      * then this includes files stored under {@link Context#getObbDir()}.
139      * <p>
140      * Code is shared between all users on a multiuser device.
141      */
getAppBytes()142     public @BytesLong long getAppBytes() {
143         return codeBytes;
144     }
145 
146     /**
147      * Return the size of the specified data type. This includes files stored under
148      * application code path.
149      * <p>
150      * If there is more than one package inside a uid, the return represents the aggregated
151      * stats when query StorageStat for package or uid.
152      * The data  is not collected and the return defaults to 0 when query StorageStats for user.
153      *
154      * <p>
155      * Data is isolated for each user on a multiuser device.
156      */
157     @FlaggedApi(Flags.FLAG_GET_APP_BYTES_BY_DATA_TYPE_API)
getAppBytesByDataType(@ppDataType int dataType)158     public long getAppBytesByDataType(@AppDataType int dataType) {
159         switch (dataType) {
160           case APP_DATA_TYPE_FILE_TYPE_DEXOPT_ARTIFACT: return dexoptBytes;
161           case APP_DATA_TYPE_FILE_TYPE_REFERENCE_PROFILE: return refProfBytes;
162           case APP_DATA_TYPE_FILE_TYPE_CURRENT_PROFILE: return curProfBytes;
163           case APP_DATA_TYPE_FILE_TYPE_APK: return apkBytes;
164           case APP_DATA_TYPE_LIB: return libBytes;
165           case APP_DATA_TYPE_FILE_TYPE_DM: return dmBytes;
166           default: return 0;
167         }
168     }
169 
170     /**
171      * Return the size of all data. This includes files stored under
172      * {@link Context#getDataDir()}, {@link Context#getCacheDir()},
173      * {@link Context#getCodeCacheDir()}.
174      * <p>
175      * If the primary external/shared storage is hosted on this storage device,
176      * then this includes files stored under
177      * {@link Context#getExternalFilesDir(String)},
178      * {@link Context#getExternalCacheDir()}, and
179      * {@link Context#getExternalMediaDirs()}.
180      * <p>
181      * Data is isolated for each user on a multiuser device.
182      */
getDataBytes()183     public @BytesLong long getDataBytes() {
184         return dataBytes;
185     }
186 
187     /**
188      * Return the size of all cached data. This includes files stored under
189      * {@link Context#getCacheDir()} and {@link Context#getCodeCacheDir()}.
190      * <p>
191      * If the primary external/shared storage is hosted on this storage device,
192      * then this includes files stored under
193      * {@link Context#getExternalCacheDir()}.
194      * <p>
195      * Cached data is isolated for each user on a multiuser device.
196      */
getCacheBytes()197     public @BytesLong long getCacheBytes() {
198         return cacheBytes;
199     }
200 
201     /**
202      * Return the size of all cached data in the primary external/shared storage.
203      * This includes files stored under
204      * {@link Context#getExternalCacheDir()}.
205      * <p>
206      * Cached data is isolated for each user on a multiuser device.
207      */
getExternalCacheBytes()208     public @BytesLong long getExternalCacheBytes() {
209         return externalCacheBytes;
210     }
211 
212     /** {@hide} */
StorageStats()213     public StorageStats() {
214     }
215 
216     /** {@hide} */
StorageStats(Parcel in)217     public StorageStats(Parcel in) {
218         this.codeBytes = in.readLong();
219         this.dataBytes = in.readLong();
220         this.cacheBytes = in.readLong();
221         this.dexoptBytes = in.readLong();
222         this.refProfBytes = in.readLong();
223         this.curProfBytes = in.readLong();
224         this.apkBytes = in.readLong();
225         this.libBytes = in.readLong();
226         this.dmBytes = in.readLong();
227         this.externalCacheBytes = in.readLong();
228     }
229 
230     @Override
describeContents()231     public int describeContents() {
232         return 0;
233     }
234 
235     @Override
writeToParcel(Parcel dest, int flags)236     public void writeToParcel(Parcel dest, int flags) {
237         dest.writeLong(codeBytes);
238         dest.writeLong(dataBytes);
239         dest.writeLong(cacheBytes);
240         dest.writeLong(dexoptBytes);
241         dest.writeLong(refProfBytes);
242         dest.writeLong(curProfBytes);
243         dest.writeLong(apkBytes);
244         dest.writeLong(libBytes);
245         dest.writeLong(dmBytes);
246         dest.writeLong(externalCacheBytes);
247     }
248 
249     public static final @android.annotation.NonNull Creator<StorageStats> CREATOR = new Creator<StorageStats>() {
250         @Override
251         public StorageStats createFromParcel(Parcel in) {
252             return new StorageStats(in);
253         }
254 
255         @Override
256         public StorageStats[] newArray(int size) {
257             return new StorageStats[size];
258         }
259     };
260 }
261