PackageManagerServiceCompilerMapping.java revision 9cea1d28dd96b05cf3cb910e03ade9dfc5146745
1/*
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 */
26public class PackageManagerServiceCompilerMapping {
27    // Names for compilation reasons.
28    static final String REASON_STRINGS[] = {
29            "first-boot", "boot", "install", "bg-dexopt", "ab-ota"
30    };
31
32    // Static block to ensure the strings array is of the right length.
33    static {
34        if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) {
35            throw new IllegalStateException("REASON_STRINGS not correct");
36        }
37    }
38
39    private static String getSystemPropertyName(int reason) {
40        if (reason < 0 || reason >= REASON_STRINGS.length) {
41            throw new IllegalArgumentException("reason " + reason + " invalid");
42        }
43
44        return "pm.dexopt." + REASON_STRINGS[reason];
45    }
46
47    // Load the property for the given reason and check for validity. This will throw an
48    // exception in case the reason or value are invalid.
49    private static String getAndCheckValidity(int reason) {
50        String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
51        if (sysPropValue == null || sysPropValue.isEmpty() ||
52                !DexFile.isValidCompilerFilter(sysPropValue)) {
53            throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
54                    + "(reason " + REASON_STRINGS[reason] + ")");
55        }
56
57        return sysPropValue;
58    }
59
60    // Check that the properties are set and valid.
61    // Note: this is done in a separate method so this class can be statically initialized.
62    static void checkProperties() {
63        // We're gonna check all properties and collect the exceptions, so we can give a general
64        // overview. Store the exceptions here.
65        RuntimeException toThrow = null;
66
67        for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) {
68            try {
69                // Check that the system property name is legal.
70                String sysPropName = getSystemPropertyName(reason);
71                if (sysPropName == null || sysPropName.isEmpty()) {
72                    throw new IllegalStateException("Reason system property name \"" +
73                            sysPropName +"\" for reason " + REASON_STRINGS[reason]);
74                }
75
76                // Check validity, ignore result.
77                getAndCheckValidity(reason);
78            } catch (Exception exc) {
79                if (toThrow == null) {
80                    toThrow = new IllegalStateException("PMS compiler filter settings are bad.");
81                }
82                toThrow.addSuppressed(exc);
83            }
84        }
85
86        if (toThrow != null) {
87            throw toThrow;
88        }
89    }
90
91    public static String getCompilerFilterForReason(int reason) {
92        return getAndCheckValidity(reason);
93    }
94
95    /**
96     * Return the default compiler filter for compilation.
97     *
98     * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make
99     * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values.
100     */
101    public static String getDefaultCompilerFilter() {
102        String value = SystemProperties.get("dalvik.vm.dex2oat-filter");
103        if (value == null || value.isEmpty()) {
104            return "speed";
105        }
106
107        if (!DexFile.isValidCompilerFilter(value) ||
108                DexFile.isProfileGuidedCompilerFilter(value)) {
109            return "speed";
110        }
111
112        return value;
113    }
114
115    /**
116     * Return the non-profile-guided filter corresponding to the given filter.
117     */
118    public static String getNonProfileGuidedCompilerFilter(String filter) {
119        return DexFile.getNonProfileGuidedCompilerFilter(filter);
120    }
121}
122