1 /*
2  * Copyright (C) 2022 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.server.art.model;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.SuppressLint;
22 import android.annotation.SystemApi;
23 import android.app.job.JobScheduler;
24 
25 import com.android.server.art.ArtManagerLocal;
26 import com.android.server.art.PriorityClass;
27 import com.android.server.art.ReasonMapping;
28 import com.android.server.pm.PackageManagerLocal;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 import java.util.List;
33 
34 /** @hide */
35 @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
36 public class ArtFlags {
37     // Common flags.
38 
39     /**
40      * Whether the operation is applied for primary dex'es (all APKs that are installed as part of
41      * the package, including the base APK and all other split APKs).
42      */
43     public static final int FLAG_FOR_PRIMARY_DEX = 1 << 0;
44     /**
45      * Whether the operation is applied for secondary dex'es (APKs/JARs that the app puts in its
46      * own data directory at runtime and loads with custom classloaders).
47      */
48     public static final int FLAG_FOR_SECONDARY_DEX = 1 << 1;
49 
50     // Flags specific to `dexoptPackage`.
51 
52     /**
53      * Whether to dexopt dependency libraries as well (dependencies that are declared by the app
54      * with <uses-library> tags and transitive dependencies).
55      */
56     public static final int FLAG_SHOULD_INCLUDE_DEPENDENCIES = 1 << 2;
57     /**
58      * Whether the intention is to downgrade the compiler filter. If true, the dexopt will
59      * be skipped if the target compiler filter is better than or equal to the compiler filter
60      * of the existing dexopt artifacts, or dexopt artifacts do not exist.
61      */
62     public static final int FLAG_SHOULD_DOWNGRADE = 1 << 3;
63     /**
64      * Whether to force dexopt. If true, the dexopt will be performed regardless of
65      * any existing dexopt artifacts.
66      */
67     public static final int FLAG_FORCE = 1 << 4;
68     /**
69      * If set, the dexopt will be performed for a single split. Otherwise, the dexopt
70      * will be performed for all splits. {@link DexoptParams.Builder#setSplitName()} can be used
71      * to specify the split to dexopt.
72      *
73      * When this flag is set, {@link #FLAG_FOR_PRIMARY_DEX} must be set, and {@link
74      * #FLAG_FOR_SECONDARY_DEX} and {@link #FLAG_SHOULD_INCLUDE_DEPENDENCIES} must not be set.
75      */
76     public static final int FLAG_FOR_SINGLE_SPLIT = 1 << 5;
77     /**
78      * If set, skips the dexopt if the remaining storage space is low. The threshold is
79      * controlled by the global settings {@code sys_storage_threshold_percentage} and {@code
80      * sys_storage_threshold_max_bytes}.
81      */
82     public static final int FLAG_SKIP_IF_STORAGE_LOW = 1 << 6;
83     /**
84      * If set, no profile will be used by dexopt. I.e., if the compiler filter is a profile-guided
85      * one, such as "speed-profile", it will be adjusted to "verify". This option is especially
86      * useful when the compiler filter is not explicitly specified (i.e., is inferred from the
87      * compilation reason).
88      */
89     @SuppressLint("UnflaggedApi") // Flag support for mainline is not available.
90     public static final int FLAG_IGNORE_PROFILE = 1 << 7;
91     /**
92      * Whether to force merge profiles even if the difference between before and after the merge
93      * is not significant.
94      *
95      * @hide
96      */
97     public static final int FLAG_FORCE_MERGE_PROFILE = 1 << 8;
98     /**
99      * Whether to force the specified compiler filter. If true, the compiler filter cannot be
100      * overridden through {@link ArtManagerLocal#setAdjustCompilerFilterCallback}. ART Service will
101      * not adjust the compiler filter either, unless dexopt cannot be performed with the specified
102      * compiler filter (e.g., the filter is "speed-profile" while no profile is available).
103      *
104      * @hide
105      */
106     public static final int FLAG_FORCE_COMPILER_FILTER = 1 << 9;
107 
108     /**
109      * Flags for {@link
110      * ArtManagerLocal#getDexoptStatus(PackageManagerLocal.FilteredSnapshot, String, int)}.
111      *
112      * @hide
113      */
114     // clang-format off
115     @IntDef(flag = true, prefix = "FLAG_", value = {
116         FLAG_FOR_PRIMARY_DEX,
117         FLAG_FOR_SECONDARY_DEX,
118     })
119     // clang-format on
120     @Retention(RetentionPolicy.SOURCE)
121     public @interface GetStatusFlags {}
122 
123     /**
124      * Default flags that are used when {@link
125      * ArtManagerLocal#getDexoptStatus(PackageManagerLocal.FilteredSnapshot, String)} is
126      * called.
127      * Value: {@link #FLAG_FOR_PRIMARY_DEX}, {@link #FLAG_FOR_SECONDARY_DEX}.
128      */
defaultGetStatusFlags()129     public static @GetStatusFlags int defaultGetStatusFlags() {
130         return FLAG_FOR_PRIMARY_DEX | FLAG_FOR_SECONDARY_DEX;
131     }
132 
133     /**
134      * Flags for {@link DexoptParams}.
135      *
136      * @hide
137      */
138     // clang-format off
139     @IntDef(flag = true, prefix = "FLAG_", value = {
140         FLAG_FOR_PRIMARY_DEX,
141         FLAG_FOR_SECONDARY_DEX,
142         FLAG_SHOULD_INCLUDE_DEPENDENCIES,
143         FLAG_SHOULD_DOWNGRADE,
144         FLAG_FORCE,
145         FLAG_FOR_SINGLE_SPLIT,
146         FLAG_SKIP_IF_STORAGE_LOW,
147         FLAG_IGNORE_PROFILE,
148         FLAG_FORCE_MERGE_PROFILE,
149         FLAG_FORCE_COMPILER_FILTER,
150     })
151     // clang-format on
152     @Retention(RetentionPolicy.SOURCE)
153     public @interface DexoptFlags {}
154 
155     /**
156      * Default flags that are used when
157      * {@link DexoptParams.Builder#Builder(String)} is called.
158      *
159      * @hide
160      */
defaultDexoptFlags(@onNull String reason)161     public static @DexoptFlags int defaultDexoptFlags(@NonNull String reason) {
162         switch (reason) {
163             case ReasonMapping.REASON_INSTALL:
164             case ReasonMapping.REASON_INSTALL_FAST:
165             case ReasonMapping.REASON_INSTALL_BULK:
166             case ReasonMapping.REASON_INSTALL_BULK_SECONDARY:
167             case ReasonMapping.REASON_INSTALL_BULK_DOWNGRADED:
168             case ReasonMapping.REASON_INSTALL_BULK_SECONDARY_DOWNGRADED:
169                 return FLAG_FOR_PRIMARY_DEX;
170             case ReasonMapping.REASON_INACTIVE:
171                 return FLAG_FOR_PRIMARY_DEX | FLAG_FOR_SECONDARY_DEX | FLAG_SHOULD_DOWNGRADE;
172             case ReasonMapping.REASON_FIRST_BOOT:
173             case ReasonMapping.REASON_BOOT_AFTER_OTA:
174             case ReasonMapping.REASON_BOOT_AFTER_MAINLINE_UPDATE:
175                 return FLAG_FOR_PRIMARY_DEX | FLAG_SHOULD_INCLUDE_DEPENDENCIES;
176             case ReasonMapping.REASON_BG_DEXOPT:
177                 return FLAG_FOR_PRIMARY_DEX | FLAG_FOR_SECONDARY_DEX
178                         | FLAG_SHOULD_INCLUDE_DEPENDENCIES | FLAG_SKIP_IF_STORAGE_LOW;
179             case ReasonMapping.REASON_CMDLINE:
180             default:
181                 return FLAG_FOR_PRIMARY_DEX | FLAG_FOR_SECONDARY_DEX
182                         | FLAG_SHOULD_INCLUDE_DEPENDENCIES;
183         }
184     }
185 
186     // Keep in sync with `PriorityClass` except for `PRIORITY_NONE`.
187     // Keep this in sync with `ArtShellCommand.printHelp` except for 'PRIORITY_NONE'.
188 
189     /**
190      * Initial value. Not expected.
191      *
192      * @hide
193      */
194     public static final int PRIORITY_NONE = -1;
195     /** Indicates that the operation blocks boot. */
196     public static final int PRIORITY_BOOT = PriorityClass.BOOT;
197     /**
198      * Indicates that a human is waiting on the result and the operation is more latency sensitive
199      * than usual.
200      */
201     public static final int PRIORITY_INTERACTIVE_FAST = PriorityClass.INTERACTIVE_FAST;
202     /** Indicates that a human is waiting on the result. */
203     public static final int PRIORITY_INTERACTIVE = PriorityClass.INTERACTIVE;
204     /** Indicates that the operation runs in background. */
205     public static final int PRIORITY_BACKGROUND = PriorityClass.BACKGROUND;
206 
207     /**
208      * Indicates the priority of an operation. The value affects the resource usage and the process
209      * priority. A higher value may result in faster execution but may consume more resources and
210      * compete for resources with other processes.
211      *
212      * @hide
213      */
214     // clang-format off
215     @IntDef(prefix = "PRIORITY_", value = {
216         PRIORITY_NONE,
217         PRIORITY_BOOT,
218         PRIORITY_INTERACTIVE_FAST,
219         PRIORITY_INTERACTIVE,
220         PRIORITY_BACKGROUND,
221     })
222     // clang-format on
223     @Retention(RetentionPolicy.SOURCE)
224     public @interface PriorityClassApi {}
225 
226     /** The job has been successfully scheduled. */
227     public static final int SCHEDULE_SUCCESS = 0;
228 
229     /** @see JobScheduler#RESULT_FAILURE */
230     public static final int SCHEDULE_JOB_SCHEDULER_FAILURE = 1;
231 
232     /** The job is disabled by the system property {@code pm.dexopt.disable_bg_dexopt}. */
233     public static final int SCHEDULE_DISABLED_BY_SYSPROP = 2;
234 
235     /**
236      * Indicates the result of scheduling a background dexopt job.
237      *
238      * @hide
239      */
240     // clang-format off
241     @IntDef(prefix = "SCHEDULE_", value = {
242         SCHEDULE_SUCCESS,
243         SCHEDULE_JOB_SCHEDULER_FAILURE,
244         SCHEDULE_DISABLED_BY_SYSPROP,
245     })
246     // clang-format on
247     @Retention(RetentionPolicy.SOURCE)
248     public @interface ScheduleStatus {}
249 
250     /**
251      * The downgrade pass, run before the main pass. Only applicable to bg-dexopt.
252      *
253      * @hide
254      */
255     public static final int PASS_DOWNGRADE = 0;
256 
257     /**
258      * The main pass.
259      *
260      * @hide
261      */
262     public static final int PASS_MAIN = 1;
263 
264     /**
265      * The supplementary pass, run after the main pass, to take the opportunity to dexopt more
266      * packages. Compared to the main pass, it uses different criteria to determine whether dexopt
267      * is needed or not, but iterates over the same packages in the same order as the main pass (so
268      * the logic in {@link ArtManagerLocal#getDefaultPackages} and {@link
269      * ArtManagerLocal.BatchDexoptStartCallback} controls the packages here too.)
270      *
271      * Only applicable to bg-dexopt.
272      *
273      * @hide
274      */
275     public static final int PASS_SUPPLEMENTARY = 2;
276 
277     /**
278      * Indicates the pass of a batch dexopt run.
279      *
280      * @hide
281      */
282     // clang-format off
283     @IntDef(prefix = "PASS_", value = {
284         PASS_DOWNGRADE,
285         PASS_MAIN,
286         PASS_SUPPLEMENTARY,
287     })
288     // clang-format on
289     @Retention(RetentionPolicy.SOURCE)
290     public @interface BatchDexoptPass {}
291 
292     /** @hide */
293     public static final List<Integer> BATCH_DEXOPT_PASSES =
294             List.of(PASS_DOWNGRADE, PASS_MAIN, PASS_SUPPLEMENTARY);
295 
ArtFlags()296     private ArtFlags() {}
297 }
298