ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package com.android.server.pm;
 
import android.os.SystemProperties;
 
import dalvik.system.DexFile;
 
/**
 * Manage (retrieve) mappings from compilation reason to compilation filter.
 */
public class PackageManagerServiceCompilerMapping {
    // Names for compilation reasons.
    public static final String REASON_STRINGS[] = {
            "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "inactive", "shared"
    };
 
    static final int REASON_SHARED_INDEX = 6;
 
    // Static block to ensure the strings array is of the right length.
    static {
        if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) {
            throw new IllegalStateException("REASON_STRINGS not correct");
        }
        if (!"shared".equals(REASON_STRINGS[REASON_SHARED_INDEX])) {
            throw new IllegalStateException("REASON_STRINGS not correct because of shared index");
        }
    }
 
    private static String getSystemPropertyName(int reason) {
        if (reason < 0 || reason >= REASON_STRINGS.length) {
            throw new IllegalArgumentException("reason " + reason + " invalid");
        }
 
        return "pm.dexopt." + REASON_STRINGS[reason];
    }
 
    // Load the property for the given reason and check for validity. This will throw an
    // exception in case the reason or value are invalid.
    private static String getAndCheckValidity(int reason) {
        String sysPropValue = SystemProperties.get(getSystemPropertyName(reason));
        if (sysPropValue == null || sysPropValue.isEmpty() ||
                !DexFile.isValidCompilerFilter(sysPropValue)) {
            throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid "
                    + "(reason " + REASON_STRINGS[reason] + ")");
        } else if (!isFilterAllowedForReason(reason, sysPropValue)) {
            throw new IllegalStateException("Value \"" + sysPropValue +"\" not allowed "
                    + "(reason " + REASON_STRINGS[reason] + ")");
        }
 
        return sysPropValue;
    }
 
    private static boolean isFilterAllowedForReason(int reason, String filter) {
        return reason != REASON_SHARED_INDEX || !DexFile.isProfileGuidedCompilerFilter(filter);
    }
 
    // Check that the properties are set and valid.
    // Note: this is done in a separate method so this class can be statically initialized.
    static void checkProperties() {
        // We're gonna check all properties and collect the exceptions, so we can give a general
        // overview. Store the exceptions here.
        RuntimeException toThrow = null;
 
        for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) {
            try {
                // Check that the system property name is legal.
                String sysPropName = getSystemPropertyName(reason);
                if (sysPropName == null || sysPropName.isEmpty()) {
                    throw new IllegalStateException("Reason system property name \"" +
                            sysPropName +"\" for reason " + REASON_STRINGS[reason]);
                }
 
                // Check validity, ignore result.
                getAndCheckValidity(reason);
            } catch (Exception exc) {
                if (toThrow == null) {
                    toThrow = new IllegalStateException("PMS compiler filter settings are bad.");
                }
                toThrow.addSuppressed(exc);
            }
        }
 
        if (toThrow != null) {
            throw toThrow;
        }
    }
 
    public static String getCompilerFilterForReason(int reason) {
        return getAndCheckValidity(reason);
    }
 
    /**
     * Return the default compiler filter for compilation.
     *
     * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make
     * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values.
     */
    public static String getDefaultCompilerFilter() {
        String value = SystemProperties.get("dalvik.vm.dex2oat-filter");
        if (value == null || value.isEmpty()) {
            return "speed";
        }
 
        if (!DexFile.isValidCompilerFilter(value) ||
                DexFile.isProfileGuidedCompilerFilter(value)) {
            return "speed";
        }
 
        return value;
    }
 
    public static String getReasonName(int reason) {
        if (reason == PackageManagerService.REASON_UNKNOWN) {
            return "unknown";
        }
        if (reason < 0 || reason >= REASON_STRINGS.length) {
            throw new IllegalArgumentException("reason " + reason + " invalid");
        }
        return REASON_STRINGS[reason];
    }
}