blob: a7512db55615a30aa8f5b1bcf9ba183914452aa8 [file] [log] [blame]
Andreas Gampebdd30d82016-03-20 11:32:11 -07001/*
2 * Copyright (C) 2016 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
17package com.android.server.pm;
18
19import android.os.SystemProperties;
20
21import dalvik.system.DexFile;
22
23/**
24 * Manage (retrieve) mappings from compilation reason to compilation filter.
25 */
26class PackageManagerServiceCompilerMapping {
Andreas Gampebdd30d82016-03-20 11:32:11 -070027 // Names for compilation reasons.
28 static final String REASON_STRINGS[] = {
Andreas Gampe6823f6d2016-03-25 17:03:28 -070029 "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk",
30 "forced-dexopt"
Andreas Gampebdd30d82016-03-20 11:32:11 -070031 };
32
33 // Static block to ensure the strings array is of the right length.
34 static {
Andreas Gampe43fc2442016-03-24 20:13:34 -070035 if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) {
Andreas Gampebdd30d82016-03-20 11:32:11 -070036 throw new IllegalStateException("REASON_STRINGS not correct");
37 }
38 }
39
40 private static String getSystemPropertyName(int reason) {
41 if (reason < 0 || reason >= REASON_STRINGS.length) {
42 throw new IllegalArgumentException("reason " + reason + " invalid");
43 }
44
45 return "pm.dexopt." + REASON_STRINGS[reason];
46 }
47
48 // Load the property for the given reason and check for validity. This will throw an
49 // exception in case the reason or value are invalid.
50 private static String getAndCheckValidity(int reason) {
51 String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
52 if (sysPropValue == null || sysPropValue.isEmpty() ||
53 !DexFile.isValidCompilerFilter(sysPropValue)) {
54 throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
55 + "(reason " + REASON_STRINGS[reason] + ")");
56 }
57
58 // Ensure that some reasons are not mapped to profile-guided filters.
59 switch (reason) {
Andreas Gampe43fc2442016-03-24 20:13:34 -070060 case PackageManagerService.REASON_SHARED_APK:
61 case PackageManagerService.REASON_FORCED_DEXOPT:
Andreas Gampebdd30d82016-03-20 11:32:11 -070062 if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) {
63 throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, "
64 + "but not allowed for " + REASON_STRINGS[reason]);
65 }
66 break;
67 }
68
69 return sysPropValue;
70 }
71
72 // Check that the properties are set and valid.
73 // Note: this is done in a separate method so this class can be statically initialized.
74 static void checkProperties() {
75 // We're gonna check all properties and collect the exceptions, so we can give a general
76 // overview. Store the exceptions here.
77 RuntimeException toThrow = null;
78
Andreas Gampe43fc2442016-03-24 20:13:34 -070079 for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) {
Andreas Gampebdd30d82016-03-20 11:32:11 -070080 try {
81 // Check that the system property name is legal.
82 String sysPropName = getSystemPropertyName(reason);
83 if (sysPropName == null ||
84 sysPropName.isEmpty() ||
85 sysPropName.length() > SystemProperties.PROP_NAME_MAX) {
86 throw new IllegalStateException("Reason system property name \"" +
87 sysPropName +"\" for reason " + REASON_STRINGS[reason]);
88 }
89
90 // Check validity, ignore result.
91 getAndCheckValidity(reason);
92 } catch (Exception exc) {
93 if (toThrow == null) {
94 toThrow = new IllegalStateException("PMS compiler filter settings are bad.");
95 }
96 toThrow.addSuppressed(exc);
97 }
98 }
99
100 if (toThrow != null) {
101 throw toThrow;
102 }
103 }
104
105 public static String getCompilerFilterForReason(int reason) {
106 return getAndCheckValidity(reason);
107 }
108
109 /**
110 * Return the compiler filter for "full" compilation.
111 *
112 * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make
113 * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values.
114 */
115 public static String getFullCompilerFilter() {
116 String value = SystemProperties.get("dalvik.vm.dex2oat-filter");
117 if (value == null || value.isEmpty()) {
118 return "speed";
119 }
120
121 if (!DexFile.isValidCompilerFilter(value) ||
122 DexFile.isProfileGuidedCompilerFilter(value)) {
123 return "speed";
124 }
125
126 return value;
127 }
128
Andreas Gampe47c170a2016-03-30 17:21:19 -0700129 /**
130 * Return the non-profile-guided filter corresponding to the given filter.
131 */
132 public static String getNonProfileGuidedCompilerFilter(String filter) {
133 return DexFile.getNonProfileGuidedCompilerFilter(filter);
134 }
Andreas Gampebdd30d82016-03-20 11:32:11 -0700135}